Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a floating point value of x, for which x-x == 0 is false?

In most cases, I understand that a floating point comparison test should be implemented using over a range of values (abs(x-y) < epsilon), but does self subtraction imply that the result will be zero?

// can the assertion be triggered?
float x = //?;
assert( x-x == 0 )

My guess is that nan/inf might be special cases, but I'm more interested in what happens for simple values.

edit:

I'm happy to pick an answer if someone can cite a reference (IEEE floating point standard)?

like image 527
Andrew Walker Avatar asked Apr 21 '10 21:04

Andrew Walker


2 Answers

As you hinted, inf - inf is NaN, which is not equal to zero. Similarly, NaN - NaN is NaN. It is true, however, that for any finite floating-point number x, x - x == 0.0 (depending on the rounding mode, the result of x - x might be negative zero, but negative zero compares equal to 0.0 in floating-point arithmetic).

Edit: it's a little tricky to give a clear standards reference, because this is an emergent property of the rules set forth in the IEEE-754 standard. Specifically, it follows from the requirement that operations defined in Clause 5 be correctly rounded. Subtraction is such an operation (Section 5.4.1 "Arithmetic operations"), and the correctly-rounded result of x - x is a zero of the appropriate sign (Section 6.3, paragraph 3):

When the sum of two operands with opposite signs (or the difference of two operands with like signs) is exactly zero, the sign of that sum (or difference) shall be +0 in all rounding-direction attributes except roundTowardNegative; under that attribute, the sign of an exact zero sum (or difference) shall be −0.

So the result of x - x must be +/- 0, and therefore must compare equal to 0.0 (Section 5.11, paragraph 2):

Comparisons shall ignore the sign of zero.

Further Edit: That's not to say that a buggy compiler couldn't cause that assert to fire. Your question is ambiguous; there is no finite floating point number x such that x - x == 0 is false. However, that's not what the code that you posted checks; it checks whether or not a certain expression in a C-style language can evaluate to a non-zero value; in particular, on certain platforms, with certain (ill-conceived) compiler optimizations, the two instances of the variable x in that expression might have different values, causing the assertion to fail (especially if x is the result of some computation, instead of a constant, representable value). This is a bug in the numerics model on those platforms, but that doesn't mean that it can't happen.

like image 190
Stephen Canon Avatar answered Nov 10 '22 18:11

Stephen Canon


If the representation is transformed (for example from 64-bit memory format to 80-bit internal register format on x86) I would expect that the assertion could possibly fire in some circumstances.

like image 4
Mark B Avatar answered Nov 10 '22 17:11

Mark B