ismember returning false for 0.6000 == 0.6
Show older comments
Hello,
I have a column of data that was created by using
A = 0.05:0.01:0.9
Secondly I am trying to obtain just the values of
B = [0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9]
However when I run
[C idx] = ismember(B,A)
it returns the logical array
[1 1 1 1 1 0 1 1 1]
[6 16 26 36 46 0 66 76 86]
I have checked the workspace and confirmed that the value 0.6000 exists within A and even when I explicitly index it returns false
A(56)
returns
0.6000
and
A(56) == 0.6
returns logical 0.
Repeating this for the other values in B results in logical 1s as array C describes.
Thank you for any help you can provide!
Accepted Answer
More Answers (2)
Tips
- Use ismembertol to perform comparisons between floating-point numbers using a tolerance
Comparisons for floating point values are subject to the inevitable internal rounding of floating point representation by binary digits; there simply is no way to represent such values exactly and the rounding between the conversion of the ASCII representation of the value won't always (as you've discovered) be the same as that from a floating point conversion.
A = 0.05:0.01:0.9;
A(56)
format long
A(56)
A(56)-0.6
shows the actual difference is at the significance level of a double precision value; with the default format of the command window, the value was displayed as 0.6000 -- note particularly the trailing zeros that imply there's more that was rounded to the requested display precision.
Hi @Jack
This is really annoying
I have once also witnesed this strange behaviour
Anyhow, this can be solved using a small "tolerance" method:
A = 0.05:0.01:0.9;
B = [0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9];
[C idx] = ismembertol(B,A,eps)
5 Comments
dpb
on 1 Jul 2024
Perhaps it is annoying, but it is inevitable and unavoidable as @Steven Lord illustrates with 10-based digits, the same can be shown for alternate values if the base is two and <Goldberg> referenced above explains how it all actually works.
Walter Roberson
on 1 Jul 2024
For any fixed numeric base N, using a finite number of positions, the value 1/(N+1) cannot be exactly represented .
For example using base 6, the values 1/2 and 1/3 can be exactly represented, but 1/7 requires an infinite number of positions.
Therefore this is a fundamental limitation on all finite rational representations with a finite number of positions. It is not specifically because MATLAB uses binary instead of decimal. No matter what the base used, if you have a finite number of positions then there will be values that cannot be exactly represented.
dpb
on 1 Jul 2024
I didn't intend nor say it was only MATLAB, just used binary becasue ML is the forum and uses base 2 owing to following IEEE.
John D'Errico
on 2 Jul 2024
I'd argue it is not even annoying. It just means you need to learn to deal with tolerances. Any choice of base will cause exactly the same problems. And if you insist on exact computations to avoid all such issues, your code will get exceedingly slow. That means if you want to do any serious computations, then you need to use some sort of floating point arithmetic. Doubles are the usual best compromise chosen, between number of bits and memory requirements. And doubles are the default choice made by most major computational environments.
Again, you might call it annoying. But is it really so? Suppose you moved to France. Would you claim it is annoying to need to learn at least a working knowledge of french? Similarly, if you would want to use MATLAB at all effectively, a working knowledge of mathematics, of your chosen field of interest, and surely of numerical analysis might all be appropriate.
Matlab Pro
on 8 Jul 2024
Thx guys! It is always a good time to improve.. Now I am smarter :-).
Categories
Find more on Logical 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!
