How do I make a floating point arithmetic more precise?

Let me show the code first, it probably can explain my question faster than in words.

int main()
{
   double n = 0.0;

   while (n < 2.5e-9) 
   {
      // perform some operation

      n += 5.0e-9;
   }   
}

Looking at the debugger, here are the values of n for each iteration:
0
5.0000000000000001e-009
1.0000000000000000e-008
1.5000000000000002e-008
2.0000000000000000e-008
2.4999999999999999e-008 (woah ! because of this, I get an extra iteration)
2.9999999999999997e-008

Now, basically I am trying to increment a float variable by 5e-9 on each loop, but it seems like the addition is not precise. I get an extra iteration because of this "imperfection".

And oh, I need to use floating point instead of integer in the while-loop statement, so "using integer instead" cannot be the solution. And the 2.5e-9 is actually a variable, therefore in different cases, it's a different value, thus doing something like:
while (n < Var - 0.000000001)
doesn't help too, because in some cases, I might lose an iteration instead.

Anyway to prevent the extra iteration?

Thanks in advance.

. . .
0
5.0000000000000001e-009
1.0000000000000000e-008
1.5000000000000002e-008
2.0000000000000000e-008
2.4999999999999999e-008 (woah ! because of this, I get an extra iteration)
2.9999999999999997e-008
. . .

What do you think of such a solution:

int main()
{
   int n = 0; double dn;
   while (n < 25)
   {  dn = 1.0e-09*n;
      // perform some operation              WITH dn
      cout << n << "   " << dn << endl;
      n += 5;
   }
}
/*
0   0
5   5e-009
10   1e-008
15   1.5e-008
20   2e-008
*/

As a rule of thumb said: Never compare floating points exactly (better: if(fabs(a-b) <= eps*fabs(b))..., where eps is small, e.g. 1.0e-10)

---
yap

Ancient-Dragon, thanks for the theoretical explanation. Cool stuff.

Yap, thanks for the possible solution. And also the insight on epsilon. Great !

This article has been dead for over six months. Start a new discussion instead.