I know the toFixed() function isn’t meant to be used for rounding, but I still can’t seem to make sense of why it sometimes rounds up and sometimes rounds down when the number ends in .5
Take a look at these examples:
toFixed(0) example
(0.5).toFixed(0)
> '1' // round up
(1.5).toFixed(0)
> '2' // round up
(2.5).toFixed(0)
> '3' // round up
(3.5).toFixed(0)
> '4' // round up
(4.5).toFixed(0)
> '5' // round up
(5.5).toFixed(0)
> '6' // round up
(6.5).toFixed(0)
> '7' // round up
(7.5).toFixed(0)
> '8' // round up
(8.5).toFixed(0)
> '9' // round up
(9.5).toFixed(0)
> '10' // round up
Consistent behavior for this example.
toFixed(1) example
(0.05).toFixed(1)
> '0.1' // round up
(1.05).toFixed(1)
> '1.1' // round up
(2.05).toFixed(1)
> '2.0' // round down
(3.05).toFixed(1)
> '3.0' // round down
(4.05).toFixed(1)
> '4.0' // round down
(5.05).toFixed(1)
> '5.0' // round down
(6.05).toFixed(1)
> '6.0' // round down
(7.05).toFixed(1)
> '7.0' // round down
(8.05).toFixed(1)
> '8.1' // round up
(9.05).toFixed(1)
> '9.1' // round up
This is where things start to break down. It seems like the first digit affects the rounding for some reason. Sometimes it rounds up and sometimes it rounds down.
toFixed(2) example
(0.005).toFixed(2)
> '0.01' // round up
(1.005).toFixed(2)
> '1.00' // round down
(2.005).toFixed(2)
> '2.00' // round down
(3.005).toFixed(2)
> '3.00' // round down
(4.005).toFixed(2)
> '4.00' // round down
(5.005).toFixed(2)
> '5.00' // round down
(6.005).toFixed(2)
> '6.00' // round down
(7.005).toFixed(2)
> '7.00' // round down
(8.005).toFixed(2)
> '8.01' // round up
(9.005).toFixed(2)
> '9.01' // round up
Even stranger is that it’s not always the same first digits that affect the rounding. You can see the results here are similar to the toFixed(1) example, but not exactly the same.
Is this a bug, some kind of browser issue, or expected behavior?
My system:
- Apple M1 Pro
- Chrome Version 116.0.5845.187
2
Answers
This is actually expected behavior with floating point precision in JS, as well as many other programming languages.
Here’s a stack overflow thread discussing. Dealing with float precision in Javascript
You could use my following code to round numbers to some decimal point with up to 10 decimals (the bigger you could get some rounding errors from
toFixed()
: