如何解决Python abs函数在负数上失败
我在 linux 上使用 python3.6,遇到了一个非常明显的 abs() 函数失败。我的变量 x
最终成为一个非常大的负数(可能是 -inf
),但绝对值 abs()
函数仍然返回一个 负 数,这不应该不可能。我通过向 abs()
的输入添加 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
编辑:下面已解决,但归结为 x
是 numpy.int64
而不仅仅是 int
,我不知道。
解决方法
您没有想到要提及它(我从您对 np.abs
的测试中推断出来的),但重要的是 x
是 numpy.int64
(或等效的有符号 64 位类型) . two's complement 中的那个特定值没有正等价物,所以 abs
只是再次产生相同的值(它可以引发异常,但 {{1} } 坚持低级 C 行为,在这种情况下它返回原始值)。
首先将其转换为真正的 Python numpy
,例如int
,它会起作用。
解释为什么会这样:
abs(int(x))
的位模式是 -9223372036854775808
(仅设置最高位,下划线便于阅读)。二进制补码取反的算法是先翻转所有位,然后加一,带进位,因此转换将 0x8000_0000_0000_0000
更改为 0x8000_0000_0000_0000
(翻转所有位),然后添加 0x7fff_ffff_ffff_ffff
,它进位字段的整个长度(因为除了高位之外的每一位都被设置),再次产生 1
。相同的位模式实际上确实对应于等于 0x8000_0000_0000_0000
的无符号 64 位数量将具有的位模式,但鉴于它被解释为有符号,它继续被解释为最负的值,而不是比最负的值高一个正值 9223372036854775808
值(不能表示为 int64
)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。