globalize
globalize copied to clipboard
An unexpected rounding result of a percentage formatted value (floating-point arithmetic issue)
To reproduce the issue, call:
Globalize('en').formatNumber(0.145, {style: 'percent', minimumFractionDigits: 0, maximumFractionDigits: 0})
Expected result: “15%”
Actual result: “14%”
The issue can be reproduced in Chrome, IE11, Edge, Mozilla Firefox.
We investigated the issue and found that the reason for unexpected rounding is multiplication by 100 in this line: https://github.com/globalizejs/globalize/blob/b08574ae714f899e50ff6a4852d9b9b8b0bc2ba0/src/number/format.js#L66. The issue is related to floating-point arithmetics. If you evaluate Math.round(0.145 * 100) in the browser console, you will get 14, because 0.145 * 100 returns 14.499999999999998.
We found that converting the number to string with the 'toFixed' method and then converting back to the number fixes the issue:
n=+((n*100).toFixed(maximumFractionDigits + 1));
A similar issue was discussed in https://github.com/globalizejs/globalize/pull/386.
Note: the Inlt localization works more predictably in this case:
Number(a).toLocaleString(undefined, { style: 'percent', minimumFractionalDigits: 0,maximumFractionDigits: 0 })
return “15%”