Answered by:
JavaScript Decimal Math

Question
-
User657329123 posted
Hello,
When I do 34.09 * 11, I get 374.99 but if I add 340.91 and 34.09 in JavaScript, I get 375.00 instead of 374.99. Here is my code:
<p id="demo"></p>
var num = (parseFloat(340.90) + parseFloat(34.09)); num = parseFloat(num).toFixed(2); document.getElementById("demo").innerHTML = n;
Why JavaScript is rounding 374.99 to 375. What do I need to do to get 374.99?
Joe
Thursday, March 4, 2021 5:10 PM
Answers
-
User-474980206 posted
javascript does not do decimal arithmetic. all numbers are 64 bit floats. floats (because they are binary rather than decimal) can not be used for money, as you will get precision errors. this is usually covered in comp sci 101, so I assume you don't have a formal edition in computer science.
just like 1/3 is .33333.. in decimal, several decimal number are repeating binaries. see:
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
the typical solution to calculating money with floats is to use a fixed precision library (like C# money) or do all the calculations in pennies (or mills if more precision required) and divide by 100 (or 1000 if mills)
> (3409 + 3409 + 3409 + 3409 + 3409) / 100
< 170.45you can do a simple javascript math package:
const pennyMath = { toPenny: (d) => Math.round(d * 100), add: (d1,d2) => (pennyMath.toPenny(d1) + pennyMath.toPenny(d2)) / 100, sub: (d1,d2) => (pennyMath.toPenny(d1) - pennyMath.toPenny(d2)) / 100, mul: (d1,d2) => Math.round(pennyMath.toPenny(d1) * pennyMath.toPenny(d2)) / 100, div: (d1,d2) => Math.round(pennyMath.toPenny(d1) / pennyMath.toPenny(d2)) / 100, sum: (...d) => d.reduce((a,c) => pennyMath.toPenny(c) + a,0) / 100 };
then:
pennyMath.sum(34.09 , 34.09 , 34.09 , 34.09 , 34.09)
gives 170.45
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, March 4, 2021 9:22 PM -
User303363814 posted
toFixed rounds to the number of decimal places requested. 170.455 when rounded to two decimal places id 170.46.
One way to truncate to two decimal places would be to multiply by 100, take the .floor (which finds the largest integer smaller than or equal to the argument) and then divide by 100. (If you want three decimal places then use 1,000 instead of 100, etc)
const truncated = (Math.floor(myNum * 100) / 100).toString();
(What do you want to do with negative numbers? The above will display -4.567 as -4.57)
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, March 4, 2021 10:28 PM
All replies
-
User475983607 posted
joegreen2005
Hello,
When I do 34.09 * 11, I get 374.99 but if I add 340.91 and 34.09 in JavaScript, I get 375.00 instead of 374.99. Here is my code:
<p id="demo"></p>
var num = (parseFloat(340.91) + parseFloat(34.09)); num = parseFloat(num).toFixed(2); document.getElementById("demo").innerHTML = n;
Why JavaScript is rounding 374.99 to 375. What do I need to do to get 374.99?
Joe
Your math is wrong.
340.91 + 34.09 = 375
Maybe you mean
340.91 + 34.08 = 374.99
Plus your code has a bug.
Thursday, March 4, 2021 6:42 PM -
User657329123 posted
The error is happening when I add 34.09 + 34.09 + 34.09 + 34.09 + 34.09, I get 170.455 and when I do 170.455.toFixed(2) I get 170.46 which should be 170.45 and not 170.46.
Thursday, March 4, 2021 7:27 PM -
User-474980206 posted
javascript does not do decimal arithmetic. all numbers are 64 bit floats. floats (because they are binary rather than decimal) can not be used for money, as you will get precision errors. this is usually covered in comp sci 101, so I assume you don't have a formal edition in computer science.
just like 1/3 is .33333.. in decimal, several decimal number are repeating binaries. see:
https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
the typical solution to calculating money with floats is to use a fixed precision library (like C# money) or do all the calculations in pennies (or mills if more precision required) and divide by 100 (or 1000 if mills)
> (3409 + 3409 + 3409 + 3409 + 3409) / 100
< 170.45you can do a simple javascript math package:
const pennyMath = { toPenny: (d) => Math.round(d * 100), add: (d1,d2) => (pennyMath.toPenny(d1) + pennyMath.toPenny(d2)) / 100, sub: (d1,d2) => (pennyMath.toPenny(d1) - pennyMath.toPenny(d2)) / 100, mul: (d1,d2) => Math.round(pennyMath.toPenny(d1) * pennyMath.toPenny(d2)) / 100, div: (d1,d2) => Math.round(pennyMath.toPenny(d1) / pennyMath.toPenny(d2)) / 100, sum: (...d) => d.reduce((a,c) => pennyMath.toPenny(c) + a,0) / 100 };
then:
pennyMath.sum(34.09 , 34.09 , 34.09 , 34.09 , 34.09)
gives 170.45
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, March 4, 2021 9:22 PM -
User303363814 posted
toFixed rounds to the number of decimal places requested. 170.455 when rounded to two decimal places id 170.46.
One way to truncate to two decimal places would be to multiply by 100, take the .floor (which finds the largest integer smaller than or equal to the argument) and then divide by 100. (If you want three decimal places then use 1,000 instead of 100, etc)
const truncated = (Math.floor(myNum * 100) / 100).toString();
(What do you want to do with negative numbers? The above will display -4.567 as -4.57)
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, March 4, 2021 10:28 PM