0

Floating point numbers are tricky, since many natural arithmetic properties don't hold.

I SUPPOSE that this particular property holds nevertheless, but I prefer to ask rather than be hit by hard to detect errors.

Assume that d is an arbitrary variable of type double. May I assume that after the following operation:

d *= 0;

The following check will always return true?

d == 0

I suppose that this will not hold if d is positive / negative infinity or NaN. However, are there any other problems I need to be aware of?

  • I hear that in floating point there are actually two zeroes, namely +0 and -0. If d is negative in the beginning, will d *= 0 return -0 instead? If so, will it be equal to 0?
  • I hear that floating point operations are subjected to inaccuracy. Thus, is it possible that multiplying by 0 will instead return something like 0.0000001 or -0.000001 which will not be equal to 0? My assumption is that this will likely be impossible, but I don't have enough knowledge to back this assumption up so I prefer to ask.
  • Any other problems I didn't foresee?

1 Answers1

2

The short answer is yes, given your specific example, d will be 0. This is because 0 has an exact representation in every FP model, so when you multiply a double by the value '0' (or '0.0'), the result is not subject to rounding/truncation errors.

The issues you mentioned come into play during FP arithmetic as a result of the inherent approximations that occur when you have a finite resolution.

For example, the most accurate 64-bit representation of the value 0.002 in the IEEE-754 floating point standard is 0x3F60624D_D2F1A9FC which amounts to 2.00000000000000004163336342344E-3 (source: http://www.binaryconvert.com/convert_double.html)

The value 0 does not suffer from this loss of precision. However, obviously if you were to do something like this, you would run into problems:

double d = 0.009;
d -= (0.001 * 9);
if (d == 0)
{
    //This check will fail
}

This is why it is almost always advised against to use exact equality when comparing floating point values.

  • I should add, that per IEEE-754 spec, it is required for +0 and -0 to evaluate as being equal. So long as the platform you're running on is compliant, there should be no issue. More info: https://en.wikipedia.org/wiki/Signed_zero – MikeFromCanmore Jul 15 '18 at 22:34
  • 3
    `.002 - .001 * 2` will not fail in normal implementations of binary floating-point because multiplication by the floating-point radix or a factor of it is exact, and, for similar reasons, the literals `.002` and `.001` are converted to the floating-point representation with rounding errors such that one is exactly twice the other. `.009 - .001 * 9` is a better example. – Eric Postpischil Jul 15 '18 at 23:32
  • Touche sir. That was a pretty lazy example on my part. Thanks for the correction. – MikeFromCanmore Jul 16 '18 at 23:22