Если вы не хотите думать о необходимости каждый раз вызывать функции, вы можете создать класс, который будет выполнять преобразование для вас.
class Decimal {
constructor(value = 0, scale = 4) {
this.intervalValue = value;
this.scale = scale;
}
get value() {
return this.intervalValue;
}
set value(value) {
this.intervalValue = Decimal.toDecimal(value, this.scale);
}
static toDecimal(val, scale) {
const factor = 10 ** scale;
return Math.round(val * factor) / factor;
}
}
Использование:
const d = new Decimal(0, 4);
d.value = 0.1 + 0.2; // 0.3
d.value = 0.3 - 0.2; // 0.1
d.value = 0.1 + 0.2 - 0.3; // 0
d.value = 5.551115123125783e-17; // 0
d.value = 1 / 9; // 0.1111
Конечно, при работе с десятичной дробью есть предостережения:
d.value = 1/3 + 1/3 + 1/3; // 1
d.value -= 1/3; // 0.6667
d.value -= 1/3; // 0.3334
d.value -= 1/3; // 0.0001
В идеале вы хотели бы использовать высокую шкалу (например, 12), а затем конвертировать ее, когда вам нужно представить ее или сохранить где-нибудь. Лично я экспериментировал с созданием UInt8Array и пытался создать значение точности (очень похожее на тип десятичного числа SQL), но, поскольку Javascript не позволяет перегрузить операторы, он просто становится немного утомительным из-за невозможности использования базовых математических операторов (+
, -
, /
, *
) и использование вместо них таких функций, как add()
, substract()
, mult()
. Для моих нужд это того не стоит.
Но если вам нужен этот уровень точности и вы готовы выдержать использование функций для математики, то я рекомендую библиотеку decimal.js .