# Why 0.6 is not equal to 0.2*3 ??

19 views (last 30 days)
Magistrane on 26 Jul 2017
Edited: Stephen23 on 10 Nov 2022 at 8:55
Hello, I have question on a really simple code :
n=(0.2*3);
m=0.6;
a=m-n
if (m==n)
trial=1;
else
trial=0;
end
when i run this code, trial = 0 and a= -1.11*10^-16. I don' get why this erreur occures :
n=(0.2*3);
m=0.6;
a=m-n
if (m==n)
trial=1;
else
trial=0;
end
This code gives a=0 and trial=1 as expected. Have someone any idea of why this is happenning and how can i compare 0.6 to 0.2*3 to get an equality? Thank you !!
Stephen23 on 26 Jul 2017
Edited: Stephen23 on 26 Jul 2017
"Have someone any idea of why this is happenning"
The reason is basically because all numbers in your computer are stored as finite binary numbers, and they cannot represent exactly those decimal fractions (in just the same way that you cannot write 1/3 exactly using a finite decimal fraction).
Your code tests for equivalence of floating point values, which is a very buggy and unreliable way to write code. You need to change your algorithm to take into account floating point error:
etc, etc, etc

Guillaume on 26 Jul 2017
In short, never use == to compare floating point numbers that come from different calculations. Always check their absolute difference against an arbitrarily small value:
if abs(m-n) <= 1e-15
AreEqual = true;
else
AreEequal = false;
end
Stephen23 on 26 Jul 2017
Edited: Stephen23 on 10 Nov 2022 at 8:55
@Magistrane: rounding introduces artificial artifacts into data because it groups data into powers of ten: this can force data values apart even though the data are much closer than the data tolerance. Compare:
>> V = [1.249,1.251];
>> diff(V)
ans = 0.002
>> roundn(V,1)
ans =
1.2 1.3
So even though the original data only differ by 0.002 (they can be arbitrarily close within floating point limits), they end up being rounded in totally different directions and have a final difference of 0.1 and would not be considered "identical" using your method. Lets say that the data/measurement tolerance is 0.05 which means that those rounded values are not matched by your method even though the original values differ by a value that is only 1/25 of the measurement tolerance! Comparing against the tolerance directly allows the values to be correctly matched:
>> abs(diff(V))<0.05
ans = 1
The converse also applies: data which are quite distinct relative to the measurement tolerance can get rounded together:
>> V = [1.151,1.249];
>> diff(V)
ans = 0.098000
>> roundn(V,1)
ans =
1.2000 1.2000
So your method groups data together that are separated by almost twice the measurement tolerance. Once again comparing against the tolerance yields a correct measure of how similar those values are:
>> abs(diff(V))<0.05
ans = 0
Summary: the best solution is to compare the difference against a tolerance.