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)?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With