我的问题是
np.array([2**31], dtype=np.uint32) >> 32
不返回0
,而是返回array([2147483648], dtype=uint32)
。
np.right_shift(np.array([2**31], dtype=np.uint32), 32)
(所以我相信这就是>>
的实现方式)。
有趣的是,所有这些替代方法似乎都能按预期工作,并返回某种0
:
print(
2**31 >> 32,
np.uint32(2**31) >> 32,
np.array(2**31, dtype=np.uint32) >> 32,
np.right_shift(2**31, 32),
np.right_shift([2**31], 32),
np.right_shift(np.uint32(2**31), 32),
np.right_shift(np.array(2**31, dtype=np.uint32), 32),
)
尤其是表示2147483648
和[2147483648]
的Numpy数组之间有什么区别?
我已经在JavaScript(Why does << 32 not result in 0 in javascript?)和C ++(Weird behavior of right shift operator (1 >> 32),Why is `int >> 32` not always zero?)中看到了这个问题,但在Python / Numpy中却没有看到。实际上,Python和Numpy文档似乎都没有记录这种行为:
答案 0 :(得分:8)
虽然没有记录,但numpy大多在C中实现,而C(和C ++)中的shift运算符未针对大于或等于位数的移位进行定义。因此结果可以是任意的。
如果您查看示例的类型,就会明白它们为什么起作用:
print(
type(2**31 >> 32),
type(np.uint32(2**31) >> 32),
type(np.array(2**31, dtype=np.uint32) >> 32),
type(np.right_shift(2**31, 32)),
np.right_shift([2**31], 32).dtype,
type(np.right_shift(np.uint32(2**31), 32)),
type(np.right_shift(np.array(2**31, dtype=np.uint32), 32)),
)
int64
第一个使用Python自己的int
类型,而其他所有都转换为numpy.int64
,其中32位移位的行为是正确的。
这主要是由于标量(零维)数组的行为不同。在list
情况下,numpy的默认整数类型为 not numpy.uint32
。
另一方面
print((np.array([2**31], dtype=np.uint32) >> 32).dtype)
uint32
所以您在这里遇到了未定义的行为。