Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 402
Vicentiu B Avatar asked Nov 06 '12 09:11

Vicentiu B


4 Answers

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.

like image 124
Anirudh Ramanathan Avatar answered Nov 15 '22 19:11

Anirudh Ramanathan


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.

like image 43
Jon Avatar answered Nov 15 '22 17:11

Jon


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

like image 26
Matthias Avatar answered Nov 15 '22 18:11

Matthias


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.

like image 20
Jon Hanna Avatar answered Nov 15 '22 19:11

Jon Hanna