If you take the intuitive approach and simply increment t
thus:
double t = 0 ;
while( t < target )
{
t += 0.00001 ;
}
You will find that the accumulated error caused by incrementing a binary floating point by a decimal real value (necessarily imprecisely converted to binary) soon causes the t
to no longer be an accurate multiple of 0.00001. To prevent that you would do better to use:
double t = 0 ;
int i = 0 ;
while( t < target )
{
t = i * 0.00001 ;
i++ ;
}
For example consider:
#include <stdio.h>
int main()
{
double target = 20000.0 ;
int i = 0 ;
double t = 0 ;
while( t < target )
{
t += 0.00001 ;
i++ ;
}
printf( "%d : %f\n", i, t ) ;
t = 0 ;
i = 0 ;
while( t < target )
{
t = i * 0.00001 ;
i++ ;
}
printf( "%d : %f\n", i, t ) ;
}
In my test the output was:
2000000037 : 20000.000005
2000000001 : 20000.000000
The first loop did 36 more iterations due to the accumulated floating point error. That may be negligible or even irrelevant in some cases, but it is a common source of confusion, error and non-deterministic behaviour that you may need to be cautious of.
That is not the most serious issue however. If the target value is very
large and the increment very small, the first loop may never terminate because the increment must first be normalised to the same precision as the value of t
and the nature of floating point representation is such that the increment may become zero. double
is good for approximately 15 significant figures do if say:
__15 digits__
/ \
target == 1000000000.00000
increment == 0.00000100000000000000
\__15 digits__/
// After normalisation:
increment == 0000000000.00000
\__15 digits__/
increment
is smaller than the precision of target
, so when increment
is transformed to the same precision, being smaller than that precision, it becomes zero, and no increment occurs. The problem becomes more acute if you use float
which is good for only 6 significant decimal digits.
Specifically with respec to your code:
#define INCREMENT 0.00001
...
double t = INCREMENT;
...
// 10.2 Calculate the simulated stopping distance
int i = 0 ;
while( v >= 0)
{
a = - f - (C_d)*(v*v);
// Calculate the new position
x_new = x + (v*t);
// Calculate the new velocity
v_new = v + (a*t);
x = x_new;
v = v_new;
// Increment t
i++ ;
t = i * INCREMENT ;
// ++t; // Not this
// t += INCREMENT // or this
}