I was working on a code requiring some rounding and number formatting, and while writing my unit tests I hit this strange case. Sometimes Number.toFixed() does not round as expected. Further investigation revealed that the rounding logic changes at number 64. Here is an example I run on MDN Number.toFixed() doc site.
function financial(x) {
return Number.parseFloat(x).toFixed(2);
}
console.log(financial(123.456));
// expected output: "123.46"
console.log(financial(0.004));
// expected output: "0.00"
console.log(financial(0.005));
// expected output: "0.01"
console.log(financial(10.005));
// expected output: "10.01"
console.log(financial(63.005));
// expected output: "63.01" <<== This is still OK.
console.log(financial(64.005));
// expected output: "64.01" <<== THIS RETURNS 64.00, NOT 64.01. WHY?
console.log(financial(100.005));
// expected output: "100.01" <<== THIS RETURNS 100.00, NOT 100.01. WHY?
console.log(financial(64.006));
// expected output: "64.01" <<== This is OK as well
console.log(financial(64.015));
// expected output: "64.02" <<== This is OK as well
console.log(financial(64.105));
// expected output: "64.11" <<== This is OK as well
console.log(financial('1.23e+5'));
// expected output: "123000.00"
From the code output, and from a few other tests that are not included, it seems like that starting with number 64 and any larger number, if there are two leading zeroes in the decimals followed by digit 5, round up does not happen for toFixed(2). I didn't try with toFixed(3) and 3 leading zeroes. However, if there is any non zero digits in the decimals, rounding happens correctly. The number 64.006 however rounds correctly to 64.01
Is this rounding behavior expected for some reason I don't understand? Is there any work around for this?
Thanks.