Number.prototype.toFixed(n)
is a number formatting method that shows n-th digits after the decimal point. It seems to rounds (n+1)-th digits. But, sometimes, it does not round up. For example, the value of 2.55.toFixed(1)
is 2.5
, not 2.6
which is correct. This example is even in MDN documents.
This strange phenomenon is due to the inaccuracy of floating points notation. What you get if you add 0.05 to 2.55? You must get a 2.6. But, in 64-bit floating points notation, the answer is as follows:
1 | > 2.55 + 0.05 |
Solution
If we want to round the digit correctly, we should not use toFixed(n)
. There are the following alternatives.
Do it in Integer
The first alternative is not using floating points, but using integer. For example, set all the currency unit to cents, not dollars.
Adding 0.5 and get the integer part in 64-bit floating points notation does no harm. Using this feature we can write another toFixed function as follows:
1 | /** |
You may use Math.round
instead of Math.floor
and + 0.5
.
1 | function toFixed(n, d) { |
Arbitrary precision libraries
If you need to calculate more precisely than 64-bit floating points notation, you would better use one of the arbitrary precision libraries. Most arbitrary precision libraries can designate precision in decimal places. Moreover, most of the libraries support toFixed
.
For example, you can see the toFixed
of big.js works correctly as follows:
1 | const Big = require('big.js'); |