float overflow?
The following code seems to always generate wrong result. I have tested it on gcc and windows visual studio. Is it because of float overflow or something else? Thanks in advance:)
#include <stdio.h>开发者_JAVA百科
#define N 51200000
int main()
{
float f = 0.0f;
for(int i = 0; i < N; i++)
f += 1.0f;
fprintf(stdout, "%f\n", f);
return 0;
}
float
only has 23 bits of precision. 512000000 requires 26. Simply put, you do not have the precision required for a correct answer.
For more information on precision of data types in C please refer this.
Your code is expected to give abnormal behaviour when you exceed the defined precision.
Unreliable things to do with floating point arithmetic include adding two numbers together when they are very different in magnitude, and subtracting them when they are similar in magnitude. The first is what you are doing here; 1 << 51200000. The CPU normalises one of the numbers so they both have the same exponent; that will shift the actual value (1) off the end of the available precision when the other operand is large, so by the time you are part way through the calculation, one has become (approximately) equal to zero.
Your problem is the unit of least precision. Short: Big float values cannot be incremented with small values as they will be rounded to the next valid float. While 1.0 is enough to increment small values the minimal increment for 16777216 seems to be 2.0 (checked for java Math.ulp, but should work for c++ too).
Boost has some functions for this.
The precision of float
is only 7 digits. Adding number 1
to a float larger than 2^24
gives a wrong result. With using double
types instead of float
you will get a correct result.
Whilst editing the code in your question, I came across an unblocked for loop
:
#include <stdio.h>
#define N 51200000
int main() {
float f = 0.0f;
for(int i = 0; i < N; i++) {
f += 1.0f;
fprintf(stdout, "%f\n", f);
}
return 0;
}
精彩评论