Why does 230/100*100 not return 230? [duplicate]
Asked Answered
C

5

10

Possible Duplicate:
Is JavaScript’s Math broken?

In Javascript, I cannot figure out why 230/100*100 returns 229.99999999999997, while 240/100*100 returns 240.

This also applies to 460, 920 and so on...

Is there any solution?

Capsaicin answered 6/11, 2012 at 9:34 Comment(3)
You can read more about it here > https://mcmap.net/q/15696/-is-floating-point-math-brokenHeterotopia
What Every Computer Scientist Should Know About Floating-Point ArithmeticJezreel
You should check this answer which contains all you need.Record
P
9

In JavaScript all numeric values are stored as IEEE 754 64-bit floating-point values (also known as double in many languages). This representation has only finite precision (so not all numbers can be accurately represented) and it is binary, so values that seem to be easy to represent in decimal can turn out to be problematic to handle.

There is no fire-and-forget solution suitable for everyone. If you need an integer then simply round using Math.round.

Palace answered 6/11, 2012 at 9:40 Comment(0)
I
10

The Issue:

230/100*100

= (230 / 100) * 100
= 2.3 * 100 in binary

2.3 in binary is the recurring decimal: 10.01001100110011001100110011001100...

This recurring decimal, cannot be accurately represented, due to limited precision, we get something like 2.29999999981373548507....


Interestingly, if you chose a division operation like such that it was accurately representable (not a recurring decimal and all digits lying within the maximum significant digits accommodated by the FP standard) in binary, you wouldn't see any such discrepancy.

E.g. 225/100*100 = 225

2.25 in binary is 10.01

Test Conversion: Binary to/from Decimal


Dealing with it:

Always be wary of precision when checking for equality between floating point values. Rounding up/down to a certain number of significant digits is good practice.

Inexpressible answered 6/11, 2012 at 9:43 Comment(0)
P
9

In JavaScript all numeric values are stored as IEEE 754 64-bit floating-point values (also known as double in many languages). This representation has only finite precision (so not all numbers can be accurately represented) and it is binary, so values that seem to be easy to represent in decimal can turn out to be problematic to handle.

There is no fire-and-forget solution suitable for everyone. If you need an integer then simply round using Math.round.

Palace answered 6/11, 2012 at 9:40 Comment(0)
H
1

This problem relates to floating point inaccuracy. See this question for more details: Is floating point math broken?

Hallagan answered 6/11, 2012 at 9:42 Comment(0)
V
0

The division in JavaScript is not integer division, but floating point.

2.3 or 2.4 can't be exactly represented in floating points. The difference is that the closest fp for 2.4 is 2.4000000953, while 2.3 is about 2.2999999523.

One can use Math.round(x) or one can use a JavaScript trick:

(x|0) converts x to integer, as the '|' operator forces the operands to integers. Even in this case 299.9943 is not rounded but truncated.

Villada answered 6/11, 2012 at 9:43 Comment(0)
J
0

For the same reason that if you were to be forced to stay to a certain precision, and to take every step, you'd give 10/3*3 as 9.99999....

Say the precision you had to keep to was 10 digits. After 10/3 you'd have 3.333333333. Then when you multiplied that by 3, you'd have 9.999999999.

Now, since we know that the 3s will go on forever, we know that the 9s will go on forever, and so we know that the answer is really 10. But that's not the deal here, the deal is you apply each step as best you can, and then go on to the next.

As well as numbers that will result in recurring representations, there could be those that could be represented precisely, but not with the number of digits you are using.

Just as 10/3 cannot be represented perfectly in decimal, so 230/100 cannot be represented perfectly in binary.

Jeneejenei answered 6/11, 2012 at 9:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.