globalize icon indicating copy to clipboard operation
globalize copied to clipboard

An unexpected rounding result of a percentage formatted value (floating-point arithmetic issue)   

Open dimarudnev opened this issue 5 years ago • 0 comments

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%”  

dimarudnev avatar Mar 01 '19 08:03 dimarudnev