From ea2c80cad018da6390ea9d116733de691907e1e4 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 3 Nov 2015 17:11:45 +0100 Subject: [PATCH] [FIX] web: Python-like rounding method Javascript and Python handle the rounding of -x.5 differently. In JS, `Math.round(-0.5)` is equal to `-0`. In Python, `round(-0.5)` is equal to `-1`. This will lead to inconsistencies between Python and Javascript, but it can also lead to inconsistencies in the Javascript itself. Indeed, in the POS, a refund to the client is entered as a negative number. For example, `4.245` will be rounded to `4.25`, but a refund of `-4.245` will be rounded to `-4.24`. The payment and the refund are not consistent. Sources: - http://www.ecma-international.org/ecma-262/6.0/index.html#sec-math.round - https://docs.python.org/2/library/functions.html#round - https://en.wikipedia.org/wiki/Rounding#Round_half_up Fixes #9249 opw-653034 --- addons/web/static/src/js/formats.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/web/static/src/js/formats.js b/addons/web/static/src/js/formats.js index 28637289429..66e77f41dae 100644 --- a/addons/web/static/src/js/formats.js +++ b/addons/web/static/src/js/formats.js @@ -350,7 +350,16 @@ instance.web.round_precision = function(value, precision){ var epsilon_magnitude = Math.log(Math.abs(normalized_value))/Math.log(2); var epsilon = Math.pow(2, epsilon_magnitude - 53); normalized_value += normalized_value >= 0 ? epsilon : -epsilon; - var rounded_value = Math.round(normalized_value); + + /** + * Javascript performs strictly the round half up method, which is asymmetric. However, in + * Python, the method is symmetric. For example: + * - In JS, Math.round(-0.5) is equal to -0. + * - In Python, round(-0.5) is equal to -1. + * We want to keep the Python behavior for consistency. + */ + var sign = normalized_value < 0 ? -1.0 : 1.0; + var rounded_value = sign * Math.round(Math.abs(normalized_value)); return rounded_value * precision; };