From a12479aaa8cb2c8311c8d6c0fceb0dc641b44eac Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Wed, 11 Mar 2020 07:44:40 +0000 Subject: [FIX] web: rounding error In JavaScript, the following computation introduces numerical errors: ``` Math.pow(10, -4) = 0.00009999999999999999 Math.pow(10, -5) = 0.000009999999999999999 ``` In the context of `round_decimals`, such errors propagate to `round_precision`, ultimately leading to inconsistencies between Python and JS (see #47300 for detailed use case). Instead of computing `Math.pow(10, decimals)`, we parse the scientific notation to prevent such inaccuracies. We also introduce tests in line with the Python tests. opw-2205092 closes odoo/odoo#47694 X-original-commit: cb471897bfa08d1fee6a9f49e90d9c120e1733fc Signed-off-by: Nicolas Martinelli (nim) --- addons/web/static/src/js/core/utils.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'addons/web/static/src/js/core') diff --git a/addons/web/static/src/js/core/utils.js b/addons/web/static/src/js/core/utils.js index 699a912ccc3..93e9bda5593 100644 --- a/addons/web/static/src/js/core/utils.js +++ b/addons/web/static/src/js/core/utils.js @@ -571,7 +571,15 @@ var utils = { * @param {Number} decimals the number of decimals. eg: round_decimals(3.141592,2) -> 3.14 */ round_decimals: function (value, decimals) { - return utils.round_precision(value, Math.pow(10,-decimals)); + /** + * The following decimals introduce numerical errors: + * Math.pow(10, -4) = 0.00009999999999999999 + * Math.pow(10, -5) = 0.000009999999999999999 + * + * Such errors will propagate in round_precision and lead to inconsistencies between Python + * and JavaScript. To avoid this, we parse the scientific notation. + */ + return utils.round_precision(value, parseFloat('1e' + -decimals)); }, /** * performs a half up rounding with arbitrary precision, correcting for float loss of precision -- cgit v1.2.3