为什么将numpy uint8移位会产生负值?

4
我可以为您翻译如下内容:

我正在使用Windows系统上的Python 2.7和Numpy 1.6.1,32位版本。 我正在编写一个函数将一些数据打包到32位整数中,并从常量值生成C源声明。 在这个过程中,我发现了Numpy的uint8类型的一些奇怪行为。

我相信没有人会感到惊讶看到这个问题:

>>> n = 0x94 << 24
>>> n
2483027968L
>>> hex(n)
'0x94000000L'

但是如果使用numpy uint8进行相同的操作,你会得到一个让我感到惊讶的结果:

>>> n = np.uint8(0x94) << 24
>>> n
-1811939328
>>> hex(n)
'-0x6c000000'

人们可能认为一个明确无符号的类型更不可能返回负值。

请注意,具有清除符号位的值按预期工作:

>>> n = np.uint8(0x74) << 24
>>> n; hex(n)
1946157056
'0x74000000'

我注意到numpy似乎在将无符号类型转换为有符号类型:

我注意到numpy似乎在将无符号类型转换为有符号类型:

>>> n = np.uint8(0x74) << 24
>>> type(n)
<type 'numpy.int32'>

这似乎是一个明显的错误。我没有找到关于这样一个已知错误的参考,但……它是吗?

1个回答

6

numpy似乎将右侧参数(24)视为本地宽度的有符号整数(在您的情况下是int32,在我的情况下是int64)。

看起来uint8被提升到相同类型,并且移位的结果也是相同类型:

>>> np.uint8(0x94) << 56
-7782220156096217088
>>> type(np.uint8(0x94) << 56)
<type 'numpy.int64'>

将右侧参数转换为无符号int会得到您期望的结果:
>>> np.uint8(0x94) << np.uint(56)
10664523917613334528
>>> type(np.uint8(0x94) << np.uint(56))
<type 'numpy.uint64'>
>>> hex(np.uint8(0x94) << np.uint(56))
'0x9400000000000000L'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接