Use the initial precision when applying factor to a field without digits
Without digits the full representation of the number is used which might not be the expected behaviour because applying the factor will result in a number which short representation could be surprising to the user. Closes #10460
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user