问题
I've found an interesting case where the same C++ code yields different results on different system.
#include <cstdio>
int main()
{
int a=20, b=14;
if(a*1.0/b*(a+1)/(b+1)==2) printf("YES!");
else printf("NO!");
}
Compiled on Ubuntu Linux 12.04 using GCC 4.6.3 it outputs YES!
Compiled on Windows 7 using GCC 4.6.2 it outputs NO!
However, using:
double c = a*1.0/b*(a+1)/(b+1);
if (c==2) printf("YES!");
...
will return YES! on both machines.
Any ideas why this difference emerges? Is this caused by compiler version mismatch (pathlevel version number shouldn't matter THAT much)? And why does it actually output NO! on the Windows machine, while this condition is obviously true?
回答1:
This is only a guess, you would need to look at the assembly output from the compiler to know for sure.
It is possible that one compiler left intermediate results in a floating-point register while the other wrote the results to memory, rounding it from 80 bits to 64. It's also possible that one uses SSE and the other does not.
回答2:
Because you are doing an equality comparison on floating-point types, which in general should not be relied upon for particular bit-exact behaviour from machine to machine (or from compiler to compiler, etc.).
Possible reasons include the compiler's choice of when to move floating-point results out of wide (80-bit) floating-point registers (neither the language standard nor the IEEE-754 floating-point standard impose any particular requirements, AFAIK).
回答3:
it is because of floating point arithmetic, try using epsilon comparisions instead:
#define EPSILON_EQUAL(a,b) ( fabs((a)-(b)) < (0.0001f) )
float f = a*1.0/b*(a+1)/(b+1);
if(EPSILON_EQUAL(f,2.0f)) printf("YES!");
回答4:
because it is not correct to compare floating point numbers like that due to precision problems.
In mathematics 2/3= (0.6666666..... to infinity)//primary school math :) no questions asked.
In computing this calculation is carried out on the floating point unit (similar to CPU but is dedicated for floating point calculations). Now this floating point unit (FPU) may give you a number very close to your actual answer but they are not exactly the same. because it will truncate the results. There is an entire field dedicated to floating point arithmetic. In short never use floating point numbers in comparisons because you may get conflicting results.
回答5:
Testing for equality between floating point numbers is problematic. This is because of rounding errors and there are many, MANY texts on this on the internet.
You can see this here, here, here, here, here and basically any result in a google search for floating point equality
.
来源:https://stackoverflow.com/questions/10519412/same-c-if-statement-different-results-on-linux-windows