The following is common knowledge for most programmers:
a = 0.3;
b = 3 * 0.1;
a == b
ans =
0
This is because 0.1
can't be represented accurately as a binary number, thus 3*0.1
become almost equal to 0.3
, but with round-off errors.
You can however obviously do the following:
a = 0.3;
a == 0.3
ans =
1
However, your problem is more complex than this... You did:
A = 0:0.1:10;
Despite what you might think, MATLAB does not create the values [0 0.1 0.2 ...]
, but rather something along the lines of [0 0+0.1 0+0.1+0.1 0+0.1+0.1+0.1 ...]
(but not really, see update in the bottom).
To illustrate this, you can have a look at the following example:
A = 0:0.1:0.4;
find(A == 0.3)
ans =
Empty matrix: 1-by-0
find(A == 0.1+0.1+0.1)
ans =
4
This however, does not really cover all aspects:
A = 5.8:0.1:6
A =
5.8000 5.9000 6.0000
find(A == 5.9)
ans =
2
%% Found it!
A = 5.8:0.1:6.1
A =
5.8000 5.9000 6.0000 6.1000
find(A == 5.9)
ans =
Empty matrix: 1-by-0
%% Didn't find it!
find(A == 5.8+0.1)
ans =
2
%% Found it again!
For the record, linspace
results in the same results.
A = linspace(5.8, 6.0, 3)
A =
5.8000 5.9000 6.0000
find(A == 5.9)
ans =
2
A = linspace(5.8, 6.1, 4)
A =
5.8000 5.9000 6.0000 6.1000
find(A == 5.9)
ans =
Empty matrix: 1-by-0
find(A == 5.8+0.1)
ans =
2
So, what's going on? Are the following two actually the same: x = [a:b:c]
and y = linspace(a,c,(c-a)/b+1)
?
A = 5.8:0.1:6.1
A =
5.8000 5.9000 6.0000 6.1000
B = linspace(5.8,6.1,4)
B =
5.8000 5.9000 6.0000 6.1000
A == B
ans =
1 1 1 1
It might appear that way... But the answer is no, they're not the same!
x = -0.1:0.1:0.3
x =
-0.1000 0 0.1000 0.2000 0.3000
y = linspace(-0.1,0.3,5)
y =
-0.1000 0 0.1000 0.2000 0.3000
x == y
ans =
1 1 0 0 1
So, what happens when you do A = 5.8:0.1:6
? How are the numbers created? And how can the following be explained?
A = 5.8:0.1:6;
B = 5.8:0.1:6.1;
A(2)-B(2)
ans =
8.8818e-016
eps(5.9)
ans =
8.8818e-016
Update:
To counteract the accumulated errors of doing [0 0+0.1 0+2*0.1 ... 0+k*0.1]
"To counteract such error accumulation, the algorithm of the COLON operator dictates that:
The first half of the output vector is calculated by adding integer multiples of the step to the left-hand endpoint. The second half is calculated by subtracting multiples of the step from the right-hand endpoint.
Also have a look here.
The lesson of course is not not compare floating point numbers using x == y
, but rather (x - y) < tolerance
.