Floating point precision can often be confusing to people.  The following code block should illustrate some important things to keep in mind about floating point numbers. In this block I am attempting to get the value 64,000,000 in two different ways.

   1: float v = 400*400*400;
   2: float w = 0;
   3:  
   4: for (int i = 0; i < 400; i++)
   5: {
   6:     for (int j = 0; j < 400; j++)
   7:     {
   8:         for (int k = 0; k < 400; k++)
   9:         {
  10:             w += 1;
  11:         }
  12:     }
  13: }
  14:  
  15: Console.WriteLine("v: " + v);
  16: Console.WriteLine("w: " + w);

On line one I am put 400*400*400 directly into the float v.  Then I declared a float w.  I have w incremented 64,000,000 times.  Once this process is done I print out the numbers.  These are the results you get:

v: 6.4E+07
w: 1.677722E+07

 

The value for v is correct but why is w not equal to v? The first instinct many might have when a number stored in a variable is wrong is that it must be an overflow.  However, v is able to display the correct value and its the same type as w.  The reason v and w are different is because of floating point precision.  A float is able to represent the number 64,000,000 but when the program attempts to get to this value by incrementing it eventually hits a road block and the variable won't change anymore.  This occurs when w becomes the values 1.677722 x 10^7.  At this point w has used up all of its mantissa (or significant digit portion) and can no longer represent the next number.   As a you store larger and larger value in a floating point number its precisions (how often it will have n+1 if it has n) decreases. (For more information about floating point numbers see Floating Point Numbers.)

 

 

CHALLENGE:

If you run the above program with optimizations on you will always get the correct answer.  My question to everyone who reads this (basically me :) ) is how are optimizations making this work differently.