Why does == not work with decimal indexed for loop?
5 次查看(过去 30 天)
显示 更早的评论
Hi everyone,
I am working with a simple data vector and I need to find the occurrences of certain values. Here is a simplified version of the code, which amounts to a for loop and an equality check:
data=[1.5 1.6 1.7 1.8 1.9 2 2.1 2.2];
%this does not work
for index=1.4:0.1:2.3
output=find(data==index)
end
%this works!
for index=1.5:0.1:2.2
output=find(data==index)
end
Running the code I see that in the first case, where only the first and last check should give an empty result, also other iterations give the "1×0 empty double row vector" output. For example, given that index=94.6 during debug, if I write the same line as "find(data==index)" it fails, if I write it with the corresponding index value it works (find(data==94.6) works). The positions where the check fails are always the same. The second for loop, with all the items matching, never fails.
Could it be a problem with the double format precision with logical operators? I have tried it in Matlab R2017a and R2013a, on different computers. I also tried to rewrite the same code without the find function, and the result is the same. If I change both data and index ranges, the behavior is the same but the check fails at different positions. All the numbers are in double format. If I multiply everything by 10, so that the numbers are integers, both loops work fine.
I would like to understand why, with decimal numbers, it doesn't work in just ONE case, the one where not all the numbers have a match.
2 个评论
Stephen23
2017-9-7
Never use == to test for equivalence of decimal values. Always compare the difference against a tolerance:
abs(A-B)<tol
And some external links on this topic:
采纳的回答
José-Luis
2017-9-7
编辑:José-Luis
2017-9-7
From the documentation:
"x = j:i:k creates a regularly-spaced vector x using i as the increment between elements. The vector elements are roughly equal to [j,j+i,j+2*i,...,j+m*i] where m = fix((k-j)/i)."
Emphasis on the roughly equal : You are running into the joys of double precision arithmetic. You should avoid comparing double precision numbers directly and use a tolerance.
You could use eps() to determine an adequate order of magnitude for the tolerance.
0 个评论
更多回答(1 个)
Guillaume
2017-9-7
What you're seeing is expected and is inherent to the way numbers are stored on computers. You'll see the same behaviour with other programming languages.
This is actually a FAQ and is all down to the fact that numbers can't all be represented exactly (particularly 0.1).
The answer is then to never use == to compare floating point values (it's fine for integers) but always use a small tolerance appropriate for the magnitude of numbers you're using.
In your case:
tolerance = 1e-20; %much smaller than your numbers magnitude
for index = 1.4:0.1:2.3
output = find(abs(data - index) <= tolerance); %check that the difference between the numbers is smaller than the tolerance
end
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Logical 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!