为什么移动numpy uint8会产生负值

  • 本文关键字:uint8 移动 numpy python numpy
  • 更新时间 :
  • 英文 :


我正在使用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似乎正在将未签名类型推广到签名类型:

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

这似乎是一个明显的错误。我找不到对这种已知错误的引用,但是...是吗?

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'

最新更新