我想测试一个数字是正数还是负数,尤其是在零的情况下。 IEEE-754 允许
-0.0
,并且它是用 Python 实现的。
我能找到的唯一解决方法是:
def test_sign(x):
return math.copysign(1, x) > 0
也许(可能需要更长的时间来运行):
def test_sign(x):
math.atan2(x, -1)
我在常用库中找不到专用函数,我是否忽略了什么?
编辑:(为什么这是相关的)
这不再是我当前的计划,但在提出问题时,我尝试根据参数是正还是负来重载函数。允许用户传递负零将解决零值输入含义的歧义。我认为这也可能引起其他用例的普遍兴趣。
您可以使用二进制表示:
import struct
def binary(num):
return ''.join(bin(ord(c)).replace('0b', '').rjust(8, '0') for c in struct.pack('!f', num))
将返回比特流给您
最高位为符号位(
0
为正,1
为负)
然而 IEEE-754 还规定 +0.0 == -0.0 == 0.0。因此无法确定
-1.0+1.0
会导致正零还是负零。
您可以使用
struct
模块直接测试位模式。
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
在 Python 标准库中,您的
copysign
方法在计算成本方面可能是最好的。按照设计,大多数事物都将正零和负零视为相同,除了除以零之类的情况,在这种情况下,它会产生巨大的差异(字面意思)。
signbit
函数可以满足你的需求。
import numpy as np
assert(np.signbit(-0.) == True)
assert(np.signbit(0.) == False)
assert(np.signbit(float('nan')) == False)