12
$\begingroup$

We are finding in Python some occasional errors in our coordinate transforms and other similar computations that produce a result of -0.0. What purpose does this serve in Python? So far it creates a zero testing error (that is, -0.0 does not equal 0.0; does it equal +0.0?).

The easy test is at the prompt:

>>> -1*0.0
$\endgroup$
3
  • 9
    $\begingroup$ There's not enough context here to provide a firm answer. The OP should read up on signed zeros in IEEE floating point. However, -0.0 is equal to +0.0 in IEEE floating point, so there's something else going on if "-0.0 does not equal 0.0" in some context. $\endgroup$ Aug 2 at 19:44
  • 5
    $\begingroup$ it has nothing to do with Python. Python uses IEEE-754 so all the floating-point rules in python is defined by the IEEE-754 standard and any languages that use IEEE-754 will have the same behavior $\endgroup$
    – phuclv
    Aug 3 at 3:44
  • 4
    $\begingroup$ If in programming, you ever find yourself testing for exact equality between floating point numbers, then you are most probably wrong. $\endgroup$
    – Glen Yates
    Aug 4 at 15:17
22
$\begingroup$

Floating point numbers (according to the standard1 nearly all programming languages use) are stored with a certain number of bits in the mantissa, in the exponent, and with a sign bit. As such, floating point numbers can make a difference between zero and minus zero. In almost all applications, that doesn't make a difference. For example, on the Python prompt, you get

>>> 0.0
0.0
>>> -1*0.0
-0.0
>>> -1*0.0 == 0.0
True

so the two compare equal.

Why are numbers not normalized so that there is only one zero? Because sometimes you want to know whether a number may have been obtained by underflow. For example:

>>> 1e-300/1e300
0.0
>>> -1e-300/1e300
-0.0

(This is because there are only so many bits in the exponent, and the smallest by magnitude number that can be stored is approximately 1e-308, so the result of the computations above is rounded down to zero.)

Of course, a completely different possibility is that you really have numbers different from zero but very small and that for whatever reason you have set up your system in such a way that everything that is smaller than a certain value is printed as zero. In those cases, even if variables a and b are shown as zero (possibly with a sign), they are not in fact zero and consequently don't compare equal.


1 For your information and further research, the standard is IEEE 754.

$\endgroup$
10
  • 8
    $\begingroup$ Division by zero raises an exception in Python, but you can use is_negative = math.copysign(1.0, x) < 0, which will be True for x = -0.0 and False for x = 0.0 $\endgroup$
    – Jasmijn
    Aug 3 at 10:15
  • 4
    $\begingroup$ @ThomasBaruchel You can, but you probably shouldn't because there are cleaner methods. Like the one Jasmijn provided. $\endgroup$
    – GammaGames
    Aug 3 at 15:27
  • 9
    $\begingroup$ Might be worth directly mentioning IEEE 754 in the answer instead of leaving it unsaid what the standard used by almost all languages is, otherwise this is an excellent answer. $\endgroup$ Aug 3 at 15:58
  • 1
    $\begingroup$ @AustinHemmelgarn That's right -- IEEE 754 is the normative source. $\endgroup$ Aug 3 at 16:59
  • 2
    $\begingroup$ I'm pretty sure that the final paragraph is what's actually going on in OP's cases, displaying as negative zero due to rounding but not actually equal to zero (either positive or negative). $\endgroup$
    – Ben Voigt
    Aug 3 at 22:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.