Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

While loop malfunction 2

Status
Not open for further replies.

nhungr

Programmer
Jan 31, 2005
26
0
0
CA

Hello. I've run into a strange problem that I can't figure out. It involves a while loop that sometimes loops one too
many times for some unknown reason. A simplified version of my code is included below:


Code:
void MyFunction(float StartTime, float TimeStep, float Interval)
{
	do
	{
		StartTime = MyLoop(StartTime,TimeStep,Interval);
	} while(StartTime<5);
	return
}

float MyLoop(float StartTime, float TimeStep, float Interval)
{
	short n=0;

	if(StartTime==0){n=1;}else{n=0;}

	[COLOR=red]while(t<StartTime+Interval+TimeStep*n)[/color]
	{		
		DoSomethingFunction();
		t+=TimeStep;
	}
	
	return t;
}


I call MyFunction with the initial values: StartTime = 0, TimeStep = 0.1, and Interval = 1. When I run it, MyLoop runs through a while loop,
incrementing the variable t by 0.1 from a starting value of 0 up to 1, and then exits the loop. Then MyFunction calls MyLoop again which again
increments t by 0.1 from a new starting value of 1.1 up to 2, etc, etc. The problem occurs when MyFunction is called the THIRD time. Insead of
t looping from 2.1 up to 3, it loops up to 3.1.
At t = 3.1, the relational operator (<) in the while expression for some reason doesn't evaluate
to false, as it should, and it loops through one extra time. This leads to the next MyLoop call starting with t = 3.2 instead of 3.1!?!?!?!?

I'm thinking it's some problem with the hidden binary values of the variables, causing some slight inprecision in the variables that isn't displayed in
the C++ debugger. I can't figure it out.

Can anyone solve the mistery???

Thanks alot,
Nikolai.
 
Explanation: You're right about the problem lying with the binary representation of the numbers. Read anything about computer-represented floating point numbers for a better explanation.


Solution: If you need exact values the way you're trying to use them, work with integers and convert them to floating point numbers as needed.

For instance, use one integer to represent the part before the decimal point and one to represent the part afterwards.

Convert to floating-point as necessary:
Code:
double value = static_cast<double>(before) + (0.1 * after)
 
Common way to go:
Code:
const double eps = 1e-5; // or -4, -6 etc (eps << step)
...
while (t < tmax + eps)
{
  if (t > tmax)
     t = tmax;
  ...
  t += ...
  ...
}
...
 

Ahah! Thank you both for clarifying the problem. Makes sense now. This is my modified code now, which works:

Code:
void MyFunction(float StartTime, float TimeStep, float Interval)
{
    do
    {
        StartTime = MyLoop(StartTime,TimeStep,Interval);
    } while(StartTime<5);
    return
}

float MyLoop(float StartTime, float TimeStep, float Interval)
{
    short n=0;

    if(StartTime==0){[COLOR=red]n=0;[/color]}else{[COLOR=red]n=-1;[/color]}

    while(t<StartTime+Interval+TimeStep*n[COLOR=red]+TimeStep/2[/color])
    {        
        DoSomethingFunction();
        t+=TimeStep;
    }
    
    return t;
}

Much appreciated.

Nikolai.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top