Why vector created by colon have improper values

1 view (last 30 days)
I'm creating vector with specified increment and later on I'm logical indexing it. When I'm looking for a value that should be present it turns out it's not there. Please explain the issue. What's the proper usage of logical indexing in such case?
x = -3:0.1:3;
any(x == 0.8) % returns 0 - no value 0.8 in -3:0.1:3;
%
x = round(x,1);
any(x == 0.8) % returns 1 - value 0.8 present in -3:0.1:3;

Accepted Answer

Jan
Jan on 20 May 2021
Edited: Jan on 20 May 2021
Welcme to the world of numerical maths.
Your question belongs to the list of Most Frequently Asked Questions:
"What's the proper usage of logical indexing in such case?"
Never compare floating point numbers by ==, but consider a tolerance. The size of this tolerance cannot be defined in general, see e.g.:
(1e17 + 1 - 1e17) * 1e6 % replies 0
(1e17 - 1e17 + 1) * 1e6 % replies 1e6
The unavoidable numerical rounding errors can be amplified by further calculations. Therefore a scientific calculation must include an analysis of the sensitivity to the initial values and parameters.

More Answers (2)

Daniel Pollard
Daniel Pollard on 20 May 2021
I'm struggling a bit to understand exactly what your question is but I think what you're asking is why the value 0.8 is not in your vector x=-3:0.1:3. The answer is that Matlab deals with floating point numbers, so the numbers stored may sometimes be off from what you expect by a very tiny amount.
The workaround, if you know what the precision of you numbers should be, is to round to that precision. Your code is as follows:
x = -3:0.1:3;
You define the vector.
x == round(0.8,1);
This asks Matlab a question. You've asked "what elements of x are exactly equal to round(0.8,1)? You'd expect the response to be a vector of zeros except at 0.8, where you'd expect a 1. This line doesn't actually do anything as you don't store or display the output.
any(x == 0.8); % returns 0 - no value 0.8 in -3:0.1:3;
As you've noted, none of the elements of x are equal to 0.8, despite your expectations that one of them will be.
x = round(x,1);
You now round all the elements of x to one significant figure.
x == round(0.8,1);
Again you ask "Are any elements of x equal to 0.8?", but now one of them is. However again you don't store or display the output so effectively it does nothing.
any(x == 0.8); % returns 1 - value 0.8 present in -3:0.1:3;
Are any of the elements of x equal to 0.8? There wasn't one before, but now there is. This is because of the rounding you did removing the floating point error.
If you want to return the position in x where 0.8 is stored, you can use code something like
x = -3:0.1:3; % Define the vector
x = round(x, 1); % Round all elements in the vector to 1 SF
pos = find(x == 0.8); % pos is the index where x = 0.8;
disp(pos)
39
disp(x(pos))
0.8000

Sulaymon Eshkabilov
Sulaymon Eshkabilov on 20 May 2021
The latter one is the right one. Since MATLAB takes up 16. cdd and thus, rounding would give us the value that we are looking at here.

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!