Как сделать правильное округление в клиентской части
Скажите, как вы округляете деньги в клиентской части?
Не хочется городить велосипеды, а пользоваться встроенными методами.
Нашел метод Terrasoft.roundValue() и даже им пользовался некоторое время, пока не поймал баг.
Terrasoft.roundValue(4758.985, 2) - вернул 4758.98
Если посмотреть исходный код, то становится понятно.
ƒ (value, decimalPlaces) {
var exponent = Math.pow(10, decimalPlaces || 0);
return Math.round(value * exponent) / exponent;
}
4758.985 * 100 = 475898.49999999994
Math.round(475898.49999999994)/100 = 4758.98, от сюда и баг.
Находил метод roundValue из миксина MoneyUtilsMixin, он считает вроде правильно, но вторым аргументом принимает не число, а объект this.roundValue(value, {"decimalPlaces": 2}), что приносит некоторые неудобства.
Если использовать метод roundMoney, то он округляет по умолчанию до 4х знаков.
Пожалуйста подскажите наиболее правильный путь?
Нравится
Алла Савельева,
не очень понимаю, что именно в этом обсуждении нужно посмотреть? Вопрос был в том, как правильно округлить число до двух знаков средствами creatio, не изобретая велосипед, а не что такое Mantissa.
Трефилов Павел Сергеевич,
Изначально неверно поняла ваш вопрос.
Для поля, которое содержит деньги, в creatio есть специальный тип 'Деньги'. Данный тип содержит 2 знака после запятой и, если у Вас получается для этого поля значение 4758.985, то система в данном случае сама должна округлить до второго знака в сторону увеличения без каких-либо дополнительных округлений со стороны разработчика.
Добавить комментарий
Алла Савельева,
а если мне нужно округлить до сохранения в бд? К примеру я считаю что-то, добавляю в переменную и сравниваю со старым значением из поля (БД).
Вообще, дробные числа, даже написанные в коде константы, сравнивать между собой опасно, как раз отличие в 0.0000000001 может проявиться. И даже сравнение разницы с Number.EPSILON помогает не всегда.
См. статьи:
Автор там вообще предлагает «to store your numbers as strings».