Javascript неправильно умножается, вызывая неправильное округление - PullRequest
5 голосов
/ 13 сентября 2011

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

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

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

Когда он умножается: 78 * 7 * 0,0725

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

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

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

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

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

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

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

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

<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>

Ответы [ 3 ]

5 голосов
/ 13 сентября 2011

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

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

0 голосов
/ 15 ноября 2017

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

new Decimal(78).mul(7).mul(0.0725) returns as expected 39.585
0 голосов
/ 23 марта 2014

Для этого может пригодиться библиотека Accounting.js . У него улучшенный метод toFixed ().

...