0.3 - 0-2 - 0.1 returns -2.7756e-17.
As is mentioned frequently in the newsgroup, some floating point numbers can not be represented exactly in binary form. So that's why you see the very small but not zero result. See EPS.
The difference is that 0:0.1:0.4 increments by a number very close to but not exactly 0.1 for the reasons mentioned below. So after a few steps it will be off whereas [0 0.1 0.2 0.3 0.4] is forcing the the numbers to their proper value, as accurately as they can be represented anyway.
a = [0 0.1 0.2 0.3 0.4];
b = 0:.1:.4;
as = sprintf('%20.18f\n',a)
>> as =
0.000000000000000000
0.100000000000000010
0.200000000000000010
0.299999999999999990
0.400000000000000020
bs = sprintf('%20.18f\n',b)
>> bs =
0.000000000000000000
0.100000000000000010
0.200000000000000010
0.300000000000000040
0.400000000000000020
and:
format hex;
hd = [a.',b.']
>> hd =
0000000000000000 0000000000000000
3fb999999999999a 3fb999999999999a
3fc999999999999a 3fc999999999999a
3fd3333333333333 3fd3333333333334
3fd999999999999a 3fd999999999999a
If you're trying to compare two floating-point numbers, be very careful about using == to do so. An alternate comparison method is to check if the two numbers you're comparing are "close enough" (as expressed by a tolerance) to one another:
areEssentiallyEqual = abs(a-b) < tol
You can see this same sort of behavior outside MATLAB. Using pencil and paper (or a chalkboard, or a whiteboard, etc.) compute x = 1/3 to as many decimal places as you want. The number of decimal places must be finite, however. Now compute y = 3*x. In exact arithmetic, y would be exactly 1; however, since x is not exactly one third but is a rounded approximation to one third, y will not be exactly 1.
Best Answer