Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I test for negative zero in Python? [duplicate]

I want to test if a number is positive or negative, especially also in the case of zero. IEEE-754 allows for -0.0, and it is implemented in Python.

The only workarounds I could find were:

def test_sign(x):
    return math.copysign(1, x) > 0

And maybe (probably takes longer to run):

def test_sign(x):
    math.atan2(x, -1)

I could not find a dedicated function anywhere in the usual libraries, did I overlook something?

Edit: (Why this was relevant)

This is not my current plan anymore, but when asking the question I tried to overload a function depending on whether an argument was positive or negative. Allowing the user to pass negative zeros would resolve the ambiguity what was meant for zero-valued input. And I think this may be of general interest for other use cases as well.

like image 612
quazgar Avatar asked Oct 11 '13 11:10

quazgar


People also ask

Does Python have negative zero?

Yes, there is a difference between 0.0 and -0.0 (though Python won't let me reproduce it :-P). If you divide a positive number by 0.0, you get positive infinity; if you divide that same number by -0.0 you get negative infinity.

Can you have a negative zero?

There's no such thing as negative zero. For a binary integer, setting the sign bit to 1 and all other bits to zero, you get the smallest negative value for that integer size. (Assuming signed numbers.) Negative zero is actually used in mathematical analysis, especially in limit calculations.

Is zero a positive number?

Positive numbers are greater than 0 and located to the right of 0 on a number line. Negative numbers are less than 0 and located to the left of 0 on a number line. The number zero is neither positive nor negative.


2 Answers

You could use the binary representation:

import struct
def binary(num):
    return ''.join(bin(ord(c)).replace('0b', '').rjust(8, '0') for c in struct.pack('!f', num))

will return you the bit stream

The highest bit is the sign bit (0 is positive, 1 is negative)

However IEEE-754 also states that +0.0 == -0.0 == 0.0. Thus can't be sure that for instance -1.0+1.0 will for instance result in a positive or negative zero.

like image 105
Willem Van Onsem Avatar answered Sep 19 '22 14:09

Willem Van Onsem


You can use the struct module to test the bit pattern directly.

import struct

def is_neg_zero(n):
    return struct.pack('>d', n) == '\x80\x00\x00\x00\x00\x00\x00\x00'

def is_negative(n):
    return ord(struct.pack('>d', n)[0]) & 0x80 != 0
like image 25
Mark Ransom Avatar answered Sep 19 '22 14:09

Mark Ransom