Подтвердить что ты не робот

Неправильное копирование Javascript, вызывающее неправильное округление

Когда я вытягиваю значения, которые я хочу размножить, они являются строками. Поэтому я их вытаскиваю, разбираю их как плавающие (для сохранения десятичных знаков) и умножаю их вместе.

LineTaxRate = parseFloat(myRate) * parseFloat(myQuantity) * parseFloat(myTaxRateRound);

Это работает на 99% моих счетов-фактур, но я обнаружил одну очень странную проблему.

При умножении: 78 * 7 * 0.0725

Возвращается Javascript: 39.58499999999999994

Когда вы обычно делаете математику в калькуляторе, ее: 39.585

Когда все сказано и сделано, я беру это число и округляю его, используя .toFixed(2)

Поскольку Javascript возвращает это число, он не округляется до желаемого значения: $39.59

Я попробовал Math.round() итог, но я все равно получаю тот же номер.

Я подумал о округлении числа до 3 десятичных знаков, затем два, но это кажется мне взломанным.

Я искал везде, и все, что я вижу, это люди, которые говорят, что parseFloat теряет свою точность и использует .toFixed, однако в приведенном выше примере это не помогает.

Вот мой тест script, который я сделал, чтобы воссоздать проблему:

<script>
var num1 = parseFloat("78");
var num2 = parseFloat("7");
var num3 = parseFloat("0.0725");
var myTotal = num1 * num2 * num3;
var result = Math.round(myTotal*100)/100

alert(myTotal);
alert(myTotal.toFixed(2));
alert(result);
</script>
4b9b3361

Ответ 1

Плавающие точки представлены в двоичном, а не в десятичном значении. Некоторые десятичные числа не будут точно представлены. И, к сожалению, поскольку Javascript имеет только один класс Number, это не очень хороший инструмент для этой работы. На других языках есть приличные десятичные библиотеки, предназначенные для предотвращения такого рода ошибок. Вам придется либо принять одноцентовые ошибки, либо реализовать решение на стороне сервера, либо работать очень сложно, чтобы исправить это.

Изменить: ooh! вы можете сделать 78 * 7 * 725, а затем разделить на 10000, или, чтобы быть точнее, просто поместите десятичную точку в нужное место. В принципе, налоговая ставка представляет собой нечто иное, чем крошечная доля. Менее удобно, но это, вероятно, позаботится о ваших ошибках умножения.

Ответ 2

Вы можете найти библиотеку Accounting.js, полезную для этого. Он имеет "улучшенный" метод toFixed().

Ответ 3

JavaScript/TypeScript имеют только один класс Number, который не так хорош. У меня такая же проблема, как и при использовании TypeScript. Я решил проблему, используя decimal.js-light.

new Decimal(78).mul(7).mul(0.0725) returns as expected 39.585