Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
While loop fails

Subject: While loop fails

From: Julio Gonzalez

Date: 21 Oct, 2011 19:27:10

Message: 1 of 14

I am trying to get a while loop to work. I have an integer T, that I converted to double using the function double. But when I print the value of double T, it shows T as an integer and not as a double. Therefore my loop fails. This is the code:

Ti=2
T = double(T);
to= 0.0000;

while (T<=to)
    to = to+0.1;
    %some code here.....
end

the loop end at to=2.0000; it should end at 2.1000

Is there any other way to fix this problems besides T=2*(1+eps)?

Regards

Julio
University of Liverpool

Subject: While loop fails

From: ScottB

Date: 21 Oct, 2011 19:57:09

Message: 2 of 14

"Julio Gonzalez" <julio@part-time-scientists.com> wrote in message <j7sh2e$q77$1@newscl01ah.mathworks.com>...
> I am trying to get a while loop to work. I have an integer T, that I converted to double using the function double. But when I print the value of double T, it shows T as an integer and not as a double. Therefore my loop fails. This is the code:
>
> Ti=2
> T = double(T);
> to= 0.0000;
>
> while (T<=to)
> to = to+0.1;
> %some code here.....
> end
>
> the loop end at to=2.0000; it should end at 2.1000
>
> Is there any other way to fix this problems besides T=2*(1+eps)?
>
> Regards
>
> Julio
> University of Liverpool

Julio,

T is a double already. I think your example is supposed to look like this:

T=2
to= 0.0000;

while (to<=T)
    to = to+0.1
    %some code here.....
end

The loop stops when to = 2. What are you trying to do?

ScottB

Subject: While loop fails

From: Julio Gonzalez

Date: 22 Oct, 2011 01:15:30

Message: 3 of 14

"ScottB" wrote in message <j7siql$37t$1@newscl01ah.mathworks.com>...
> "Julio Gonzalez" <julio@part-time-scientists.com> wrote in message <j7sh2e$q77$1@newscl01ah.mathworks.com>...
> > I am trying to get a while loop to work. I have an integer T, that I converted to double using the function double. But when I print the value of double T, it shows T as an integer and not as a double. Therefore my loop fails. This is the code:
> >
> > Ti=2
> > T = double(T);
> > to= 0.0000;
> >
> > while (T<=to)
> > to = to+0.1;
> > %some code here.....
> > end
> >
> > the loop end at to=2.0000; it should end at 2.1000
> >
> > Is there any other way to fix this problems besides T=2*(1+eps)?
> >
> > Regards
> >
> > Julio
> > University of Liverpool
>
> Julio,
>
> T is a double already. I think your example is supposed to look like this:
>
> T=2
> to= 0.0000;
>
> while (to<=T)
> to = to+0.1
> %some code here.....
> end
>
> The loop stops when to = 2. What are you trying to do?
>
> ScottB
Hi Scott,

It is a simple while loop. T is integer equal to 2; "to" increments 0.1 on each pass of the loop until it reaches 2.0. It works while (to<2). But it fails in the checking when
to = T = 2.

If I print T, I can see only the number "2"... No decimal point.

I can not make T double even if I explicitly makes it double. But if I apply T = 2*(1+eps) then I can see now T= 2.0000 and the while loop terminates correctly...

Julio

Subject: While loop fails

From: Roger Stafford

Date: 22 Oct, 2011 03:09:15

Message: 4 of 14

"Julio Gonzalez" <julio@part-time-scientists.com> wrote in message <j7sh2e$q77$1@newscl01ah.mathworks.com>...
> ......
> to = to+0.1;
> ......
- - - - - - - -
  Julio, after twenty executions of the line

 to = to+0.1;

starting with 'to' equal to zero, the value of 'to' will not be an exact 2.0, but rather 2+2^(-51), which is greater than 2 by a very tiny amount. You can use 'format hex' to show this. Does this explain things? This error is caused by the fact that a binary floating point number cannot be exactly equal to 0.1 = 1/10 for just the same reason that decimal fractions can never be exactly equal to 1/3. After twenty additions by this slightly erroneous value it is only in excess of an exact 2.0 by one bit at its least significant end, but that is presumably enough to cause trouble with the method you are using in your loop. You need to alter your method, perhaps by counting with integers.

Roger Stafford

Subject: While loop fails

From: Parag S. Chandakkar

Date: 22 Oct, 2011 03:02:18

Message: 5 of 14

On Oct 21, 6:15 pm, "Julio Gonzalez" <ju...@part-time-scientists.com>
wrote:
> "ScottB" wrote in message <j7siql$37...@newscl01ah.mathworks.com>...
> > "Julio Gonzalez" <ju...@part-time-scientists.com> wrote in message <j7sh2e$q7...@newscl01ah.mathworks.com>...
> > > I am trying to get a while loop to work. I have an integer T, that I converted to double using the function double. But when I print the value of double T, it shows T as an integer and not as a double. Therefore my loop fails. This is the code:
>
> > > Ti=2
> > > T = double(T);
> > > to= 0.0000;
>
> > > while (T<=to)
> > >     to = to+0.1;
> > >     %some code here.....
> > > end
>
> > > the loop end at to=2.0000; it should end at 2.1000
>
> > > Is there any other way to fix this problems besides T=2*(1+eps)?
>
> > > Regards
>
> > > Julio
> > > University of Liverpool
>
> > Julio,
>
> > T is a double already. I think your example is supposed to look like this:
>
> > T=2
> > to= 0.0000;
>
> > while (to<=T)
> >     to = to+0.1
> >     %some code here.....
> > end
>
> > The loop stops when to = 2. What are you trying to do?
>
> > ScottB
>
> Hi Scott,
>
> It is a simple while loop.  T is integer equal to 2; "to" increments 0.1 on each pass of the loop until it reaches 2.0. It works while (to<2). But it fails in the checking when
> to = T = 2.
>
> If I print T, I can see only the number "2"... No decimal point.
>
> I can not make T double even if I explicitly makes it double. But if I apply T = 2*(1+eps) then I can see now T= 2.0000 and the while loop terminates correctly...
>
> Julio

Hi,

Don't you think that the condition T<=t0 i.e. 2<=0.1 is false on first
iteration; therefore; it doesn't even enter into that loop. There is
another catch in this on which there are already enough articles on
the web. If you write the program as:

T=2
T = double(T);
to= 0.0000;
while (T>=to)
    to = to+0.1;
to
    %some code here.....
end

Then logically it should give output as to=2.1 but it doesn't since
you have defined to=0.0000, so at the end of the loop t=2.0000 + eps
(since you have defined only 4 digits in a double precision format...
so the difference between T and to is to-T=4.4409e-016.
You will find a lot of articles on the web if you search this number.
I am not discussing it here. I will give you one link:
http://www.eng-tips.com/viewthread.cfm?qid=253704

You can write your program like this to get it working:

clear all;
clc;
T=2;
T = double(T); %statement doesn't make a difference
to= 0;
while (T-to>=eps || abs(to-T)<=10*eps)
    to = to+0.1;
to
    %some code here.....
end

Hope this helps.
Regards,
- Parag Shridhar Chandakkar.

Subject: While loop fails

From: Julio Gonzalez

Date: 22 Oct, 2011 15:01:29

Message: 6 of 14

"Parag S. Chandakkar" <parag2489@gmail.com> wrote in message <86476fac-163d-4e6e-99e0-0373558ecc9d@t38g2000prg.googlegroups.com>...
> On Oct 21, 6:15 pm, "Julio Gonzalez" <ju...@part-time-scientists.com>
> wrote:
> > "ScottB" wrote in message <j7siql$37...@newscl01ah.mathworks.com>...
> > > "Julio Gonzalez" <ju...@part-time-scientists.com> wrote in message <j7sh2e$q7...@newscl01ah.mathworks.com>...
> > > > I am trying to get a while loop to work. I have an integer T, that I converted to double using the function double. But when I print the value of double T, it shows T as an integer and not as a double. Therefore my loop fails. This is the code:
> >
> > > > Ti=2
> > > > T = double(T);
> > > > to= 0.0000;
> >
> > > > while (T<=to)
> > > >     to = to+0.1;
> > > >     %some code here.....
> > > > end
> >
> > > > the loop end at to=2.0000; it should end at 2.1000
> >
> > > > Is there any other way to fix this problems besides T=2*(1+eps)?
> >
> > > > Regards
> >
> > > > Julio
> > > > University of Liverpool
> >
> > > Julio,
> >
> > > T is a double already. I think your example is supposed to look like this:
> >
> > > T=2
> > > to= 0.0000;
> >
> > > while (to<=T)
> > >     to = to+0.1
> > >     %some code here.....
> > > end
> >
> > > The loop stops when to = 2. What are you trying to do?
> >
> > > ScottB
> >
> > Hi Scott,
> >
> > It is a simple while loop.  T is integer equal to 2; "to" increments 0.1 on each pass of the loop until it reaches 2.0. It works while (to<2). But it fails in the checking when
> > to = T = 2.
> >
> > If I print T, I can see only the number "2"... No decimal point.
> >
> > I can not make T double even if I explicitly makes it double. But if I apply T = 2*(1+eps) then I can see now T= 2.0000 and the while loop terminates correctly...
> >
> > Julio
>
> Hi,
>
> Don't you think that the condition T<=t0 i.e. 2<=0.1 is false on first
> iteration; therefore; it doesn't even enter into that loop. There is
> another catch in this on which there are already enough articles on
> the web. If you write the program as:
>
> T=2
> T = double(T);
> to= 0.0000;
> while (T>=to)
> to = to+0.1;
> to
> %some code here.....
> end
>
> Then logically it should give output as to=2.1 but it doesn't since
> you have defined to=0.0000, so at the end of the loop t=2.0000 + eps
> (since you have defined only 4 digits in a double precision format...
> so the difference between T and to is to-T=4.4409e-016.
> You will find a lot of articles on the web if you search this number.
> I am not discussing it here. I will give you one link:
> http://www.eng-tips.com/viewthread.cfm?qid=253704
>
> You can write your program like this to get it working:
>
> clear all;
> clc;
> T=2;
> T = double(T); %statement doesn't make a difference
> to= 0;
> while (T-to>=eps || abs(to-T)<=10*eps)
> to = to+0.1;
> to
> %some code here.....
> end
>
> Hope this helps.
> Regards,
> - Parag Shridhar Chandakkar.

Hi Parag,

Thank you for your answer. The first paragraph you are right but it does not apply to my case.

I will take a look at those links you gave me. Also, thanks for confirming my suspicions about the reason. The problem is the "eps" approximation...

Regards

Subject: While loop fails

From: dpb

Date: 22 Oct, 2011 18:06:23

Message: 7 of 14

On 10/21/2011 8:15 PM, Julio Gonzalez wrote:
...

> It is a simple while loop. T is integer equal to 2; ...

no, No, NO!!!

T is a (Matlab default) double which _contains_ an integral value of 2.

Insert

whos T

after the line T=2 if you don't believe it.

> ... "to" increments 0.1
> on each pass of the loop until it reaches 2.0. It works while (to<2).
> But it fails in the checking when to = T = 2.
> If I print T, I can see only the number "2"... No decimal point.
> I can not make T double even if I explicitly makes it double. But if I
> apply T = 2*(1+eps) then I can see now T= 2.0000 and the while loop
> terminates correctly...

This depends on your definition of "correctly".

Use

format long

to see the long value of any intermediate values (or display the values
of t0-2 to amplify the floating point remainder).

As another respondent said, the "problem" is one of floating point
precision and the use of t+dt is the most error-accumulating way one can
possibly find to compute a running total; if dt is under the exact value
by one bit, that one bit short will accumulate every iteration through.
  OTOH, if you were to compute the time as t=n*dt, the error would
average out.

Try the two following examples at the command line...

x=0;for idx=1:10000,x=x+0.1;end, x-1000

and for comparison

x=0;for idx=1:10001,x=(idx-1)*0.1;end, x-1000

--

Subject: While loop fails

From: Julio Gonzalez

Date: 23 Oct, 2011 15:10:28

Message: 8 of 14

dpb <none@non.net> wrote in message <j7v0n2$qof$1@speranza.aioe.org>...
> On 10/21/2011 8:15 PM, Julio Gonzalez wrote:
> ...
>
> > It is a simple while loop. T is integer equal to 2; ...
>
> no, No, NO!!!
>
> T is a (Matlab default) double which _contains_ an integral value of 2.
>
> Insert
>
> whos T
>
> after the line T=2 if you don't believe it.
>
> > ... "to" increments 0.1
> > on each pass of the loop until it reaches 2.0. It works while (to<2).
> > But it fails in the checking when to = T = 2.
> > If I print T, I can see only the number "2"... No decimal point.
> > I can not make T double even if I explicitly makes it double. But if I
> > apply T = 2*(1+eps) then I can see now T= 2.0000 and the while loop
> > terminates correctly...
>
> This depends on your definition of "correctly".
>
> Use
>
> format long
>
> to see the long value of any intermediate values (or display the values
> of t0-2 to amplify the floating point remainder).
>
> As another respondent said, the "problem" is one of floating point
> precision and the use of t+dt is the most error-accumulating way one can
> possibly find to compute a running total; if dt is under the exact value
> by one bit, that one bit short will accumulate every iteration through.
> OTOH, if you were to compute the time as t=n*dt, the error would
> average out.
>
> Try the two following examples at the command line...
>
> x=0;for idx=1:10000,x=x+0.1;end, x-1000
>
> and for comparison
>
> x=0;for idx=1:10001,x=(idx-1)*0.1;end, x-1000
>
> --

Hi dpb,

THis was my confusion. When I printed T, I got T=2, and I printed to, I got 0.1000... then I incorrectly though that T was an integer.

Now I understand my problem... the accumulation error in MATLAB. Next time I will me more careful when designing loops such that.

Thanks Scott, dpb and Srivana...

Subject: While loop fails

From: dpb

Date: 23 Oct, 2011 15:38:05

Message: 9 of 14

On 10/23/2011 10:10 AM, Julio Gonzalez wrote:
...

> Now I understand my problem... the accumulation error in MATLAB....


Again, no, No, NO, _NO_!!!! :(

You apparently don't appreciate the basis of the problem at all. :(

It has absolutely _nothing_ to do with Matlab but _everything_ to do
with floating point representation.

Read (thoroughly) Goldberg's exposition at

<http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html>

--

Subject: While loop fails

From: Julio Gonzalez

Date: 23 Oct, 2011 18:40:10

Message: 10 of 14

With all due respect,

I do appreciate the nature of the problem, , I thought MATLAB will be more intelligent and will deal correctly with the answer. Other programming languages can handle this problem in much better way. I tried the same loop in other programming languages and all of them give the correct answer!

 Even a simple PERL script can handle the problem... IMHO, MATLAB could do a better job that PERL..

I understand MATLAB is an engineer tool and it is the engineer that must handle the issue..

Thanks for the link.. next time I will pay more attention to this problem while working with MATLAB! Thank you for shearing the information..

dpb <none@non.net> wrote in message <j81cd0$8uc$1@speranza.aioe.org>...
> On 10/23/2011 10:10 AM, Julio Gonzalez wrote:
> ...
>
> > Now I understand my problem... the accumulation error in MATLAB....
>
>
> Again, no, No, NO, _NO_!!!! :(
>
> You apparently don't appreciate the basis of the problem at all. :(
>
> It has absolutely _nothing_ to do with Matlab but _everything_ to do
> with floating point representation.
>
> Read (thoroughly) Goldberg's exposition at
>
> <http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html>
>
> --

Subject: While loop fails

From: Roger Stafford

Date: 23 Oct, 2011 19:04:15

Message: 11 of 14

"Julio Gonzalez" <julio@part-time-scientists.com> wrote in message <j81n2a$j0b$1@newscl01ah.mathworks.com>...
> I do appreciate the nature of the problem, , I thought MATLAB will be more intelligent and will deal correctly with the answer. Other programming languages can handle this problem in much better way. I tried the same loop in other programming languages and all of them give the correct answer!
>
> Even a simple PERL script can handle the problem... IMHO, MATLAB could do a better job that PERL..
>
> I understand MATLAB is an engineer tool and it is the engineer that must handle the issue..
> .........
- - - - - - - - - -
  Julio, if by "the problem" you mean that your 'to' variable doesn't end up an exact value of 2 after twenty iterations of "to = to+0.1", then you are quite wrong in singling out the matlab language as being responsible. Any programming system that uses binary floating point numbers will of necessity exhibit a similar behavior. It is inherent in the nature of binary representation of floating point numbers with a finite number of digits. You would do well to study up on the subject. Understanding these principles is fundamental to writing good mathematical programs.

Roger Stafford

Subject: While loop fails

From: Julio Gonzalez

Date: 23 Oct, 2011 21:10:31

Message: 12 of 14

"Roger Stafford" wrote in message <j81off$mrp$1@newscl01ah.mathworks.com>...
> "Julio Gonzalez" <julio@part-time-scientists.com> wrote in message <j81n2a$j0b$1@newscl01ah.mathworks.com>...
> > I do appreciate the nature of the problem, , I thought MATLAB will be more intelligent and will deal correctly with the answer. Other programming languages can handle this problem in much better way. I tried the same loop in other programming languages and all of them give the correct answer!
> >
> > Even a simple PERL script can handle the problem... IMHO, MATLAB could do a better job that PERL..
> >
> > I understand MATLAB is an engineer tool and it is the engineer that must handle the issue..
> > .........
> - - - - - - - - - -
> Julio, if by "the problem" you mean that your 'to' variable doesn't end up an exact value of 2 after twenty iterations of "to = to+0.1", then you are quite wrong in singling out the matlab language as being responsible. Any programming system that uses binary floating point numbers will of necessity exhibit a similar behavior. It is inherent in the nature of binary representation of floating point numbers with a finite number of digits. You would do well to study up on the subject. Understanding these principles is fundamental to writing good mathematical programs.
>
> Roger Stafford

Hi Roger,

You are right. I will. Precisely I was doing some tests in C++ and it has the same behaviour. I will take a look to the webpage dbd sent to me and will be more careful to consider the errors introduced by the round-off.

Thanks to all.

Subject: While loop fails

From: Steven_Lord

Date: 24 Oct, 2011 03:22:14

Message: 13 of 14



"Julio Gonzalez" <julio@part-time-scientists.com> wrote in message
news:j81n2a$j0b$1@newscl01ah.mathworks.com...
> With all due respect,
> I do appreciate the nature of the problem, , I thought MATLAB will be more
> intelligent and will deal correctly with the answer.

It does. It returns the correct answer using standard IEEE double precision
floating-point arithmetic.

http://www.mathworks.com/company/newsletters/news_notes/pdf/Fall96Cleve.pdf

> Other programming languages can handle this problem in much better way. I
> tried the same loop in other programming languages and all of them give
> the correct answer!

If they're using some form of arbitrary precision arithmetic (for example)
they could add (exactly) 1/10 twenty times and that would give (exactly) 2.
That's fine.

Now try writing that exact same loop in another language that uses IEEE
arithmetic, like C or C++ using the double data type. The results should
agree with those returned by MATLAB.

Welcome to the world of floating-point arithmetic.

*snip*

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: While loop fails

From: Bill Whiten

Date: 25 Oct, 2011 09:44:13

Message: 14 of 14

"Julio Gonzalez" <julio@part-time-scientists.com> wrote in message <j7sh2e$q77$1@newscl01ah.mathworks.com>...
> I am trying to get a while loop to work. I have an integer T, that I converted to double using the function double. But when I print the value of double T, it shows T as an integer and not as a double. Therefore my loop fails. This is the code:
>
> Ti=2
> T = double(T);
> to= 0.0000;
>
> while (T<=to)
> to = to+0.1;
> %some code here.....
> end
>
> the loop end at to=2.0000; it should end at 2.1000
>
> Is there any other way to fix this problems besides T=2*(1+eps)?
>
> Regards
>
> Julio
> University of Liverpool

T=2;
s=0.1;
n=round(T/s)
for i=1:n
to=T*i/n;
. . .

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us