【问题标题】:Integer limit crossed while performing bitwise left shift operation in array在数组中执行按位左移操作时超过整数限制
【发布时间】:2018-09-12 18:18:39
【问题描述】:

我正在使用按位左移运算符创建一个 numpy 数组。

例如,我创建数组p,其中数组的形状与矩阵a的形状相同,即(23,):

>>> import numpy
>>> a = numpy.array([0,0,0,0,0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,0,0,1,1])

>>> p = 1 << arange(a.shape[-1] - 1) #left shift 

结果如预期:

>>> p
array([      1,       2,       4,       8,      16,      32,      64,
       128,     256,     512,    1024,    2048,    4096,    8192,
     16384,   32768,   65536,  131072,  262144,  524288, 1048576,
   2097152])

但是,如果我们增加数组的大小,假设为 (70,):

>>> a = numpy.array([0,0,0,0,0,0,1,0,1,0,1,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
>>> p = 1 << arange(a.shape[-1] - 1, -1, -1) #left shift 
>>> p
array([                   1,                    2,                    4,
                      8,                   16,                   32,
                     64,                  128,                  256,
                    512,                 1024,                 2048,
                   4096,                 8192,                16384,
                  32768,                65536,               131072,
                 262144,               524288,              1048576,
                2097152,              4194304,              8388608,
               16777216,             33554432,             67108864,
              134217728,            268435456,            536870912,
             1073741824,           2147483648,           4294967296,
             8589934592,          17179869184,          34359738368,
            68719476736,         137438953472,         274877906944,
           549755813888,        1099511627776,        2199023255552,
          4398046511104,        8796093022208,       17592186044416,
         35184372088832,       70368744177664,      140737488355328,
        281474976710656,      562949953421312,     1125899906842624,
       2251799813685248,     4503599627370496,     9007199254740992,
      18014398509481984,    36028797018963968,    72057594037927936,
     144115188075855872,   288230376151711744,   576460752303423488,
    1152921504606846976,  2305843009213693952,  4611686018427387904,
   -9223372036854775808,                    0,                    0,
                      0,                    0,                   16])

在顶部,您可以看到随着它从 1、2、4、8 增加,..... 变为负数,然后是 0,最后是 16。

如果我单独做的话,情况就不是这样了:

>>> 1<<70
1180591620717411303424

那么,我该怎么做才能使我的数组元素的值对应于1&lt;&lt;x,其中 x 是一个大数(大于 70)?

【问题讨论】:

  • Python ints 和 numpy ints 不一样...
  • 具体来说,python int 是可变精度的,并且是支持它的非常重的对象。 Numpy 整数反映固定宽度的整数。

标签: python arrays numpy bit-manipulation


【解决方案1】:

Python int 和 numpy int 不一样... Python 支持任意长度,而 numpy 是由类型固定的:

numpy.array([1]) << 70
>>> array([64], dtype=int32)

一种解决方案是使用 object dtype:

numpy.array([1], dtype=numpy.object) << 70
>>> array([1180591620717411303424], dtype=object)

以下将按预期工作:

a = numpy.array([1], dtype=numpy.object) << numpy.arange(70)

查看最后一个元素的类型,我们看到它是一个 Python int:

type(a[-1])
>>> <class 'int'>

【讨论】:

  • 谢谢。你的工作太棒了!但是正如您提到的,object dtype 具有很大的性能损失。我们可以做些什么来改善这一点吗?我这样做基本上是为了提高我的表现!
  • @appsdownload:你应该问一个关于性能方面的单独问题......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 2019-09-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多