I wonder what would be the shortest and safest way to achieve the following:
Suppose I have a float var with the value 1.200123
. In our visualization, I want to show this value with two decimal places, so I use myFloat.toFixed(2);
at the moment, which gives me 1.20
.
That's fine. But what if the resulting output only has zeros at the decimal places? For example the value 1.000043
which becomes 1.00
.
For the case above: how can I omit the decimal point and the zeros and just get 1
as output, preferrably without parsing and manipulating the string that comes out of .toFixed(2)
?
...preferrably without parsing and manipulating the string that comes out of .toFixed(2)?
Well, you could do it numerically, though I'd worry about getting a perfect match between numeric logic and toFixed
's logic , given the definition of toFixed
includes phrases like:
Let n be an integer for which the exact mathematical value of n ÷ 10 f - x is as close to zero as possible. If there are two such n , pick the larger n .
So I'd probably just update the string, it's not a lot of work:
function formatNumber(num) { return num.toFixed(2).replace(/\\.00$/, ""); } function test(num) { console.log(num, "=>", formatNumber(num)); } test(1.01); test(1.43); test(23.7); test(1.200123); test(1.000043); test(1.007); test(1.0007);
But here's an approximate numeric approach, which at least matches the results for the test cases above:
function formatNumber(num) { var check = Math.round(num * 100) / 100; var rounded = Math.round(check); if (rounded == check) { return String(rounded); } return num.toFixed(2); } function formatNumberViaToFixed(num) { return num.toFixed(2).replace(/\\.00$/, ""); } function test(num) { var formatted = formatNumber(num); var viaToFixed = formatNumberViaToFixed(num); if (formatted == viaToFixed) { console.log(num, "=>", formatted); } else { console.log(num, "=>", formatted, "ERROR: Should be", viaToFixed); } } test(1.01); test(1.43); test(23.7); test(1.200123); test(1.000043); test(1.007); test(1.0007);
.as-console-wrapper { max-height: 100% !important; }
I would create this conditional toFixed
method within the Number
prototype, which in the end will call the this.toFixed
method so that you will keep that original behavior and only adjust the amount of digits passed to it - that can be easily done with Math.pow
and Math.trunc
.
Object.defineProperty(Number.prototype, 'toConditionalFixed', { enumerable: false, writable: false, configurable: false, value: function(digits) { let comp = Math.pow(10, digits); return this.toFixed(Math.trunc(this * comp) % comp === 0 ? 0 : digits); } }); console.log( (1.200123).toConditionalFixed(2), '|', (1.200123).toConditionalFixed(3), '|', (1.200123).toConditionalFixed(4), '|', (1.000043).toConditionalFixed(2), '|', (1.000043).toConditionalFixed(3), '|', (1.000043).toConditionalFixed(4), '|', (1.000043).toConditionalFixed(5) );
EDIT
For the sake of completeness, the same method within Number.prototype
which works with RegExp:
Object.defineProperty(Number.prototype, 'toConditionalFixed', { enumerable: false, writable: false, configurable: false, value: function(digits) { let re = new RegExp("\\\\." + "0".repeat(digits) + "$"); return this.toFixed(digits).replace(re, ""); } }); console.log( (1.200123).toConditionalFixed(2), '|', (1.200123).toConditionalFixed(3), '|', (1.200123).toConditionalFixed(4), '|', (1.000043).toConditionalFixed(2), '|', (1.000043).toConditionalFixed(3), '|', (1.000043).toConditionalFixed(4), '|', (1.000043).toConditionalFixed(5) );
You could use Number(myFloat.toFixed(2))
.
While this produces a value with type number
rather than string
, you can use it in a string expression (implicitly calling its .toString()
method), or call .toString()
explicitly, to produce the string format you want.
As Number.toString()
does no special formatting, converting the string to a number and then back removes trailing zeroes from rounded value produced by .toFixed()
.
The downside of this method would be that it converts 1.10
to "1.1"
rather than "1.10"
, which may or may not be what you want for your visualisation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.