Why 0.6 is not equal to 0.2*3 ??

9 views (last 30 days)
Magistrane
Magistrane on 26 Jul 2017
Edited: Stephen23 on 10 Nov 2022
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 !!
  1 Comment
Stephen23
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

Sign in to comment.

Answers (1)

Guillaume
Guillaume on 26 Jul 2017
You need to learn more about floating point numbers:
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
  6 Comments
Magistrane
Magistrane on 26 Jul 2017
Thank you again for your anwer, At the end i used roundn() function which match with the utilisation in my algo. Until now, it works, should I expect other supprises with this? ^^" If you say yes, I surrend and will take hours to change my loop, other way, thank you again for the explanations it was really usefull! Have a good day!
Stephen23
Stephen23 on 26 Jul 2017
Edited: Stephen23 on 10 Nov 2022
@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.

Sign in to comment.

Categories

Find more on Characters and Strings in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!