Comparing doubles to double literals? [duplicate]
Possible Duplicate:
How should I do floating point comparison?
Is it not recommended to compare for equality a double and a double literal in C++, because I guess it is compiler dependent?
To be more precise it is not OK to compare a double which is hard-coded (a literal in the source code) and a double which should be computed, as the last number of the resultant of the calculation can vary from one compiler to another. Is this not standardized?
I heard this is mentioned in Knuth's TeXbook, is that right?
If this is all true, what is the soluti开发者_JAVA技巧on?
You've misunderstood the advice a bit. The point is that floating-point computations aren't exact. Rounding errors occur, and precision is gradually lost. Take something as simple as 1.0/10.0
. The result should be 0.1
, but it isn't, because 0.1
cannot be represented exactly in floating-point format. So the actual result will be slightly different. The same is true for countless other operations, so the point has nothing to do with const doubles. It has to do with not expecting the result to be exact. If you perform some computation where the result should be 1.0
, then you should not test it for equality against 1.0
, because rounding errors might mean that it actually came out 0.9999999997
instead.
So the usual solution is to test if the result is sufficiently close to 1.0
. If it is close, then we assume "it's good enough", and act as if the result had been 1.0.
The bottom line is that strict equality is rarely used for floating-point values. Instead, you should test if the difference between the two values is less than some small value (typically called the epsilon)
The problem you are talking about is due to rounding errors and will happen for every floating point number. What you can do is define an epsilon and see if the difference between the two floating point numbers is smaller than this. E.g.:
double A = somethingA();
double B = somethingB();
double epsilon = 0.00001;
if (abs(A - B) < epsilon)
doublesAreEqual();
[Edit] Also see this question: What is the most effective way for float and double comparison?.
The key problem is how floating point arithmetic works - it includes rounding that can lead to comparison for equality evaluated wrong. This applies to all floating point numbers regardless of whether variable is declared const
or not.
if you do floating point calculations and you need to do comparisons with certain fixed values it is always safer to use an epsilon value to take into account precision errors .
Example:
double calcSomeStuf();
if ( calcSomeStuf() == 0.1 ) { ...}
is a bad idea
however:
const double epsilon = 0.005
double calcSomeStuf();
if ( abs(calcSomeStuf() - 0.1) < epsilon ) { ...}
is a lot safer (especially considering the fact that 0.1 cannot be represented exactly as a double)
This is necessary because when accumulating floating point operations rounding errors occur, and due to the nature of floating point not all numbers can be represented exactly
精彩评论