Javascript multiplying incorrectly, causing incorrect rounding
javascript, math, parsefloat
Solution
Floating points are represented in binary, not decimal. Some decimal numbers will not be represented precisely. And unfortunately, since Javascript only has one Number class, it's not a very good tool for this job. Other languages have decent decimal libraries designed to avoid precisely this kind of error. You're going to have to either accept one-cent errors, implement a solution server-side, or work very hard to fix this.
edit: ooh! you can do 78 * 7 * 725 and then divide by 10000, or to be even more precise just put the decimal point in the right place. Basically represent the tax rate as something other than a tiny fraction. Less convenient but it'll probably take care of your multiplication errors.
Problem
When I pull the values I want to multiply, they're strings. So I pull them, parse them as floats (to preserve the decimal places), and multiply them together. ``` LineTaxRate = parseFloat(myRate) * parseFloat(myQuantity) * parseFloat(myTaxRateRound); ``` This has worked for 99% of my invoices but I discovered one very odd problem. When it multiplied: 78 * 7 * 0.0725 Javascript is returning: 39.584999999999994 When you normally do the math in a calculator its: 39.585 When all is said and done, I take that number and round it using .toFixed(2) Because Javascript is returning that number, it's not rounding to the desired value of: $39.59 I tried Math.round() the total but I still get the same number. I have thought of rounding the number to 3 decimals then two, but that seems hacky to me. I have searched everywhere and all I see is people mention parseFloat loses its precision, and to use .toFixed, however in the example above, that doesn't help. Here is my test script i made to recreate the issue: ``` <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> ```