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?

hakre
  • 193,403
  • 52
  • 435
  • 836
Trap
  • 12,050
  • 15
  • 55
  • 67

6 Answers6

12

Here's the updated site which discusses the pros and cons of several methods of comparing floating point numbers. (You can still view the old site here.)

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.

jhenninger
  • 931
  • 7
  • 17
nickf
  • 537,072
  • 198
  • 649
  • 721
5

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
  • 65,341
  • 56
  • 178
  • 228
4

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
  • 398,270
  • 210
  • 566
  • 880
2

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
  • 384,516
  • 81
  • 508
  • 779
  • 1
    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 Oct 25 '08 at 15:20
  • @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 Oct 25 '08 at 16:48
  • 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 Oct 25 '08 at 20:03
  • @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 Oct 25 '08 at 20:25
  • I used "== 0" just today. It's safe enough. A method that calculates the overlap area between two rectangles returns 0 if there is no overlap. Surely I can test whether the result is zero. – Qwertie Dec 17 '10 at 23:05
  • @Qwertie - but what if the result of your calculation is `-0`, or `2e-1074`, do those count as "no overlap"? – OrangeDog Mar 29 '12 at 11:23
  • @Qwertie: "Safe Enough"? What can that possibly mean? If you're using floating-point values, and your rectangles are **huge**, then the overlap may be non-zero, but wind up truncated down to zero because of float-point calculation issues. You can't compare with zero. – S.Lott Mar 30 '12 at 23:55
  • @S.Lott "Safe enough" depends on the application. If you really, really need to detect 0.00000000000000001% overlap between fantastically large rectangles, well, I guess, just to be safe, the overlap detector could return -1 to represent "no overlap" to distinguish it from 0 meaning "overlap so small it was rounded to 0", and then the caller can safely do "overlap(a, b) == -1" on the result instead. But certainly for my application and most others, returning 0 is sufficiently unambiguous. – Qwertie Apr 18 '12 at 20:35
  • @OrangeDog, (-0 == 0) == true. And my function doesn't return 2e-1074 when it detects that there is no overlap, it returns 0 exactly. – Qwertie Apr 18 '12 at 20:38
  • @Qwertie, you seem to be missing the point. If there is a 0.00000000000000001% overlap (which we agree should probably count as no overlap), then doing `getOverlap() == 0` will be false (i.e. it says that there is an overlap). – OrangeDog Apr 19 '12 at 09:12
  • @OrangeDog Well, if the function returns anything that is not zero, whether it's 2e-1074 or whatever, then (getOverlap() == 0) == false which is A GOOD THING since there is overlap. I didn't say 0.00000000000000001% overlap *shouldn't* count as any overlap, I said that for my application, comparison with 0 is sufficiently unambiguous which means that in a case of infitessimal overlap it *doesn't fricking matter at all* whether the comparison is true or false. – Qwertie Jun 06 '12 at 19:23
1

http://www.windojitsu.com/code/floatcomparer.html

-1

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.

Martin Liesén
  • 1,308
  • 11
  • 14
  • 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 Oct 25 '08 at 16:12
  • 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. – Martin Liesén Oct 25 '08 at 19:39