0

I found this code snippet on Page 174, A Book on C -Al Kelley, Ira Pohl .

int main()
{
 int cnt=0; double sum=0.0,x; 
 for( x=0.0 ;x!= 9.9 ;x+=0.1)
 {
   sum=sum +x;
   printf("cnt = %5d\n",cnt++);
 }
 return 0;

}

and it became a infinite loop as the book said it would. It didnt mention the precise reason except saying that it had to do with the accuracy of the machine.

I modified the code to check if x=9.9 would ever become true, i.e. x was attaining 9.9 by adding the following lines

 diff=x-9.9;
 printf("cnt =10%d  \a x =%10.10lf  dif=%10.10lf \n",++cnt,x,diff);

and i got the following lines among the output

 cnt =1098   x =9.7000000000  dif=-0.2000000000 
 cnt =1099   x =9.8000000000  dif=-0.1000000000 
 cnt =10100   x =9.9000000000  dif=-0.0000000000 
 cnt =10101   x =10.0000000000  dif=0.1000000000 
 cnt =10102   x =10.1000000000  dif=0.2000000000 

if x is attaining the value 9.9 exactly , why is it still a infinite loop?

nemesis
  • 3
  • 3
  • 1
    From where came `X`...??? Did you mean `sum != 9.9` in the `for` loop condition. – 0xF1 May 14 '14 at 06:46
  • 4
    [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – Some programmer dude May 14 '14 at 06:48
  • This is a duplicate of many similar questions. Bottom line - double precision cannot represent `0.1` exactly, so you end up that `99*0.1 != 9.9`. – Floris May 14 '14 at 06:49

4 Answers4

1

The problem is that most floating point implementation are based on IEEE 754. See http://en.wikipedia.org/wiki/IEEE_floating_point

The problem with this is, that numbers are builded with base 2 (binary formats).

The number 9.9 can never be build with base 2 excatly.

The "Numerical Computation Guide" by David Goldberg gves an exact statement about it:

Several different representations of real numbers have been proposed, but by far the most widely used is the floating-point representation. Floating-point representations have a base b (which is always assumed to be even) and a precision p. If b = 10 and p = 3, then the number 0.1 is represented as 1.00 × 10^-1. If b = 2 and p = 24, then the decimal number 0.1 cannot be represented exactly, but is approximately 1.10011001100110011001101 × 2^-4.

bkausbk
  • 2,740
  • 1
  • 36
  • 52
1

You are simply printing the number with too poor accuracy to notice that it isn't exact. Try something like this:

#include <stdio.h>

int main()
{
  double d = 9.9;

  if(d == 9.9)
  {
    printf("Equal!");
  }
  else
  {
    printf("Not equal! %.20f", d);
  }
}

Output on my machine:

Not equal! 9.90000000000000035527

The book is likely trying to teach you to never use == or != operators to compare floating point variables. Also for the same reason, never use floats as loop iterators.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

You can safely assume two floating point numbers are never equal 'exactly' (unless one is a copy of the other).

CiaPan
  • 9,381
  • 2
  • 21
  • 35
0

Computer works on binary and floating point, in other words in base 2. Just like base 10, base 2 have numbers that it cannot build. For example, try to write the fraction 10/3 in base 10. You'll end up with infinite 3s. and in Binary, you cannot even write 0.1 (decimal) in binary, you'll also get a recurring pattern 0.0001100110011... (binary).

This video will do better to explain http://www.youtube.com/watch?v=PZRI1IfStY0

Isaac
  • 158
  • 10