diff --git a/sao/src/model.js b/sao/src/model.js index 6d0ac60a09..df6926c6c8 100644 --- a/sao/src/model.js +++ b/sao/src/model.js @@ -2062,12 +2062,23 @@ }, apply_factor: function(record, value, factor) { if (value !== null) { + // The default precision is the one used by value (before + // applying the factor), per the ecmascript specification + // it's the shortest representation of said value. + // Once the factor is applied the number might become even + // more inexact thus we should rely on the initial + // precision + the effect factor will have + // https://tc39.es/ecma262/multipage/ecmascript-data-types-and-values.html#sec-numeric-types-number-tostring + let default_precision = (value.toString().split('.')[1] || '').length; + default_precision += Math.ceil(Math.log10(factor)); value /= factor; var digits = this.digits(record); if (digits && (digits[1] !== null)) { // Round to avoid float precision error // after the division by factor value = value.toFixed(digits[1]); + } else { + value = value.toFixed(default_precision); } value = this.convert(value); } diff --git a/tryton/tryton/gui/window/view_form/model/field.py b/tryton/tryton/gui/window/view_form/model/field.py index 0312a2c865..36abd46c47 100644 --- a/tryton/tryton/gui/window/view_form/model/field.py +++ b/tryton/tryton/gui/window/view_form/model/field.py @@ -459,10 +459,20 @@ class FloatField(Field): def apply_factor(self, record, value, factor): if value is not None: + # The default precision is the one used by value (before + # applying the factor), as python uses the shortest representation + # of said value. + # Once the factor is applied the number might become even + # more inexact thus we should rely on the initial + # precision + the effect factor will have + default_precision = len((str(value).split('.', 2) + [''])[1]) + default_precision += math.ceil(math.log10(factor)) value /= factor digits = self.digits(record) if digits: value = round(value, digits[1]) + else: + value = round(value, default_precision) value = self.convert(value) return value