views:

823

answers:

6

Or is there a chance that the operation will fail?

Thanks.

I chose the wrong term and what I really meant was rounding to 0, not truncation.

The point is, I need to compare the integer part of two doubles and I'm just casting them to int and then using ==, but, as someone pointed out in one of my earlier questions, this could throw an overflow exception if the double can't fit into the integer.

So the question would be 'Is it correct to use the == operator to compare two doubles that have previously been rounded to 0, or should I stick to the casting to int method and catch a possible exception?

+4  A: 

It can still fail due to the normal problems with floating point representation. Rather than truncating them, use a delta that would represent the equivalent precision.

It can fail in cases where you have two floats that you would normally consider the same,

10.19999999

10.20000001

but when you truncate them they give different results.

10.19

10.20

Whereas, if I had used a delta of 0.001 to compare to the difference, I would have seen that these two values are effectively the same.

Bill the Lizard
+10  A: 

Here's a site which discusses the pros and cons of several methods of comparing floating point numbers.

The method I'd go with is the "relative error" method. Find the difference between the two numbers, convert that to a percentage of the numbers, and if that percentage is sufficiently small, then you've got equality.

nickf
+2  A: 

It's never correct to use == with floating-point.

What does "truncate" mean in a float-point context? What specific library function are you calling? What is the result? What makes you believe that "truncated" values are any more comparable than non-truncated values?

Floating point is an approximation of decimal values. Floating point can only represent powers of two precisely. All other values are subject to some error, no matter what floating-point operations you do.

If, however, you convert to integer, you can use ==.

S.Lott
Never say "never". If you have a relatively calculation calculation that involves numbers which are exactly representable in IEEE 754, then it can be ok to use ==, but these situations are rare.
Adam Rosenfield
@Adam Rosenfield: the "exactly representable" clause would be irrelevant. If you know the result of an expression, you would just use the answer. If you wrote a program, you didn't know the result, and you didn't know if it's exactly representable. Never use ==.
S.Lott
What if you're writing a unit test for something that does some amount of floating-point math? If you know exactly what the answer should be, you should use == in that case. Never say "never".
Adam Rosenfield
@Adam Rosenfield: Still disagree. That's a unit test, not application programming. Unit tests can be fragile and depend on specific library versions and hardware. That exception is so rare, so minor and so easy to get wrong that I stand by my crazy absolutism. Never use ==.
S.Lott
A: 

If your absolut value is less than 2^23 for single or 2^52 for double you can use round() and then do the compare. Larger values can not be precisly stored and this opens for situations where N == N+1.

mliesen
That would require rounding, not truncation. Granted, i'm not entirely certain what the OP means by truncation (ceil()?), but presumably if he meant rounding he would have said so...
Shog9
Ceil is not the same as Trunc when it comed to negative numbers. My point was that taken rounding/truncing/ceiling/flooring out of the equation, you can safly do the compare.
mliesen
+3  A: 

Even worse is that sometimes, even for the exact same number, it will fail. This is because some compilers or processors will use more bits of precision in a CPU register than in memory (MSVC has 3 different floating-point behavior options, for example). Thus a recently-computed value may not have these bits truncated and will appear to be unequal. NEVER use == on floats.

rlbond