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.
float v = 400400400; float w = 0; for (int i = 0; i < 400; i++) { for (int j = 0; j < 400; j++) { for (int k = 0; k < 400; k++) { w += 1; } } } Console.WriteLine(“v: “ + v); 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.