summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/core/utils.js
diff options
context:
space:
mode:
authorNicolas Martinelli <nim@odoo.com>2020-03-11 07:44:40 +0000
committerNicolas Martinelli <nim@odoo.com>2020-03-16 12:01:57 +0000
commita12479aaa8cb2c8311c8d6c0fceb0dc641b44eac (patch)
treebb3aca9fcf4003f644feaecf64739c5fed341d80 /addons/web/static/src/js/core/utils.js
parent0067aec0ddaf75d2608a6acc12cb26c08f70d12e (diff)
[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) <nim@odoo.com>
Diffstat (limited to 'addons/web/static/src/js/core/utils.js')
-rw-r--r--addons/web/static/src/js/core/utils.js10
1 files changed, 9 insertions, 1 deletions
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