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.

Here's why floating point is not very accurate. It talks about Python but applies to all other programming languages too that use Intel Floating Point. If you need more accuracy then use one of the several alternate math libraries.

. . .
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 !

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.