While loop going one too far

6 views (last 30 days)
Andy Kong
Andy Kong on 3 Nov 2016
Answered: Mostafa on 3 Nov 2016
While learning to use while loops, I came across this comparison between a for and while loop.
%%For loop
for i = 1:0.2:2
y = i^2;
end
%%While loop
i = 1;
while i < 2
y = i^2;
i = i + 0.2;
end
However, these two loops don't evaluate to the same thing. The for loop has i reaching 2, but the while loop has an ending i value of 2.2, which means when i=2, it still entered the while loop despite 2 < 2 being false. How is this possible? Shouldn't i exit when i=2 since 2<2 returns false?

Accepted Answer

Alexandra Harkai
Alexandra Harkai on 3 Nov 2016
Seems like the same problem as here .

More Answers (1)

Mostafa
Mostafa on 3 Nov 2016
Ah, the good old "Hard equality" problem.. Simply put, (i<2) doesn't return false, since (i) is not actually equal to (2) !
This happened because you added increments of floating-point value (0.2), where most floating-point values can't be accurately stored and must be approximated (0.199999999999) or (0.20000000001) for example . So what happened is that (i) never the reached the exact value of (2), and the expression (i<2) didn't evaluate to false.
So, what you can do is this:
i = 1;
%Let's change the condition a bit
while (2-i) >= 1e-10
y = i^2;
i = i + 0.2;
end
%Let's check the actual data
format long
i
%%i = 2.0000000000
y
%%y = 3.2399999999
%Can you see the precision problem in here?
Here we used a different expression: (2-i) >= 1e-10,
we took the difference between the the two numbers and compared it to an arbitrary value (1e-10 or 1*10^-10 or 0.0000000001) which is basically zero.
Let me emphasise on that: It is NOT zero, but it CAN be considered as zero, since the difference is very small.
for i = 1:0.2:2
y = i^2;
end
You might ask, but why did this not happen in the case of the for loop? Well, that because you defined (i) with specific increments from the start in i = 1:0.2:2. This makes a huge difference for the method of storing the data in the memory, and results in saving it as something called "Fixed point" instead of "Floating point", which retains the precision and is preferred to be used in a lot of programming languages.
TLDR: For numbers with precision (432.631 for example), never use relational operator as it is, instead use a comparison with an arbitrary zero value ((440 - 432.631) > 1e-5). For more about this topic, search online for "Fixed point vs Floating point" or read this topic.

Categories

Find more on Function Creation 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!