Obtuse Systems Corporation
Home
Resources
Contact Us

IEEE 754 concepts - negative zero


The IEEE 754 binary floating point arithmetic standard has the concept of both a positive zero and a negative zero.

A negative zero results from:

  • an operation which generates a negative value which is too small to be represented in the floating point precision being used.

    For example, both -10-200 * 10-200 and -10-200 / 10200 result in negative zero.

  • the division of a positive finite value by -infinity or the division of a negative finite value by +infinity1.

    For example, 1.0 / ( -10200 * 10200 ) will result in negative zero.

  • the multiplication of a positive finite value by negative zero or the multiplication of any negative finite value by positive zero.

    For example, 1.0 * ( 10-200 * -10-200 ) will result in negative zero.

With two exceptions that we'll get to shortly, a negative zero can't be distinguished from a positive zero. For example, if x is negative zero (or positive zero) then the following will print out "they are the same":
if ( x == 0.0 ) then
print "they are the same"
else
print "they are different"
fi
Two IEEE 754 operations can be used to distinguish between a positive zero and a negative zero:
  1. dividing a positive finite value by negative zero results in -infinity (as does dividing a negative finite value by positive zero). Conversely, dividing a positive finite value by positive zero results in +infinity (as does dividing a negative finite value by negative zero).

    For example, if x is negative zero then the following will print out "x is negative":

    if ( 1.0 / x < 0 ) then
    print "x is negative"
    else
    print "x is positive (or we got a NaN)"
    fi
    
  2. the IEEE 754 CopySign function can be used to extract the sign of an IEEE 754 floating point value. This value can then be tested to determine if the original value was positive or negative.

    For example, if x is negative zero then the following will print "x is negative" (CopySign returns the value of the first operand but with the sign of the second operand):

    y = CopySign(1.0,x)
    if ( y < 0 ) then
    print "x is negative"
    else
    print "x is positive"
    fi
    
Negative zeros can "create the opportunity for an educational experience" when they are printed as they are often printed as "-0" or "-0.0" (the "educational experience" is the time and effort that you spend learning why you're getting these strange values).

A single precision negative zero is represented in memory as the bit pattern 0x80000000 whereas a single precision positive zero is represented as 0x00000000. A double precision negative zero is represented as 0x8000000000000000 whereas a double precision positive zero is represented as 0x0000000000000000. Testing IEEE 754 values for zero by using non-IEEE 754 operations (e.g. checking if a memory location is all zeros using integer operations) can provide yet another "opportunity for an educational experience".


References


1IEEE 754 also has the concept of infinity values. Please see our IEEE 754 concepts - NaNs page for a short sidebar discussion of IEEE 754 infinities.


Origins

This document was originally written by a member of the Obtuse team as a contribution to the Everything2 site. It appears on the Obtuse web site and on the Everything2 site here with the permission of the author.