Sum of three variables: strange behavior

Possible duplicate:
Is there a bug in javascript? Why decimal numbers cannot be represented exactly in binary format?

What will be the result of the following code:

if(0.3 == ( 0.1 + 0.1 + 0.1 )) { alert(true); } else { alert(false); } 

This is strange, but the result will be false.

The reason is that the result

0.1 + 0.1 + 0.1

will be

+0.30000000000000004

How can this behavior be explained?

+6
source share
4 answers

The explanation is pretty simple - read about Floating Point Problems

+1
source

For the same reason, 1/3 + 1/3 + 1/3 may not give you exactly 1 in decimal. If you use 1/3 as .33333333, then 1/3 + 1/3 + 1/3 will give you .9999999 , which is not exactly one.

Unless you know exactly what you are doing, do not compare non-integer numeric types for equality.

+2
source

This is due to the nature of the floats stored on computers. There is no such thing as an exact way to store an arbitrary floating point number. What you usually do when comparing floats is to see if the difference is different from a small number of epsilon, for example:

 function equals(f1, f2){ var epsilon = 0.00001; //arbitrary choice return (f1-f2 < epsilon && f2-f1 < epsilon); } 

so in your case, change if (0.3 == (0.1 + 0.1 + 0.1)) to if (equal to 0.3, (0.1 + 0.1 + 0.1))

+1
source

What you are experiencing is the main floating point rounding error.

We cannot represent exactly 0.1 without some error due to the nature of binary numbers. WolframAlpha reports the decimal value of 0.1 into equal binary ~ 0.00011001100110011 ... Note how it cannot be finally represented in a binary number system? This means that we must decide on the cut-off point at which to stop calculating this number, otherwise we would be here forever.

This results in an error. And this error has accumulated as the code adds numbers together, which leads to an incredibly small amount added to the end of your amount. This ensures that the amount will never be EXACTLY 0.3 that the IF test is looking for.

Some decimal numbers, however, can be represented exactly in binary form, such as dec 0.5 = bin 0.1 and dec 0.25 = bin 0.01.

We can demonstrate this in the same way as the original code, using 0.5 = (0.25 + 0.25).


For further reference, I recommend the Floating Point Guide .

It gives a good overview of the concept of floating point numbers and how computational errors can occur. There is also a section on Javascript that demonstrates how to overcome the rounding errors you experience.

+1
source

Source: https://habr.com/ru/post/898360/


All Articles