Python abs()函数在负数上失败

jk_*_*sri 1 python numpy absolute-value python-3.x python-3.6

我在 linux 上使用 python3.6,遇到了一个非常明显的 abs() 函数失败。我的变量x最终变成了一个非常大的负数(可能是-inf),但绝对值abs()函数仍然返回一个负数,这应该是不可能的。我通过在abs()but....的输入中添加 0.1 来快速修复我的代码,我是否误解了abs()应该如何使用?

$> x
-9223372036854775808

$> abs(x)
-9223372036854775808

$> np.abs(x)
-9223372036854775808

$> abs(x+.1)
9.223372036854776e+18

$> np.abs(x+.1)
9.223372036854776e+18
Run Code Online (Sandbox Code Playgroud)

编辑:在下面解决了,但归结x为一个numpy.int64而不仅仅是int我不知道的。

Sha*_*ger 8

您没有想到提及它(我从您的测试中推断出它np.abs),但重要的x是它是numpy.int64(或等效的有符号 64 位类型)。该特定值,在二进制补码中,没有正等价物,因此abs只需再次生成相同的值(它可能会引发异常,但numpy在这种情况下它会返回原始值的低级 C 行为卡住了)。

首先将其转换为真正的 Python int,例如abs(int(x)),它将起作用。


解释为什么它以这种方式工作:

的位模式-92233720368547758080x8000_0000_0000_0000(仅设置最高位,下划线以提高可读性)。二的补否定通过翻转所有的位,然后加入一个,带进位算法处理,所以所述转换改变0x8000_0000_0000_00000x7fff_ffff_ffff_ffff(所有位翻转),然后增加1,其承载所述场的整个长度(因为每个位,但高比特是设置),0x8000_0000_0000_0000再次生产。相同的位模式实际上确实对应于一个无符号的 64 位数量等于9223372036854775808将具有的位模式,但鉴于它被解释为有符号,它继续被解释为最负的值,而不是比最正值高一个int64值(即不能表示为int64)。

  • @paradox:不是投反对票的人之一,但我明白了;OP 忽略告诉我们“x”是“numpy”类型。虽然我的心灵调试能力非常棒,在这种情况下,我几乎 100% 确定它们达到了目标(如果不是的话,我会限制自己发表评论),但省略关键细节的问题(例如库)使用和变量的定义)没有提供[MCVE],并且可以说是“坏的”。 (3认同)