【问题标题】:Left shifting 1 by large numbers using numpy array使用 numpy 数组将 1 左移大数
【发布时间】:2015-02-08 14:17:41
【问题描述】:

Python 确实可以左移大整数位

1L << 100
# 1267650600228229401496703205376L

但是 NumPy 貌似有问题:

a = np.array([1,2,100])
output = np.left_shift(1L,a)
print output 
# array([          2,           4, 68719476736])

有没有办法使用 NumPy 的 left_shift 操作来克服这个问题?单独访问数组元素会产生同样的错误结果:

1L << a[2]
# 68719476736

【问题讨论】:

    标签: python arrays python-2.7 numpy bit-shift


    【解决方案1】:

    Python long 值与 a 中保存的整数类型不同。具体来说,Python long 的值不限于 32 位或 64 位,而是可以占用任意数量的内存。

    另一方面,NumPy 会将a 创建为int32 或int64 整数值的数组。当你左移这个数组时,你会得到一个相同数据类型的数组。这没有足够的内存来保存1 &lt;&lt; 100,并且左移的结果会溢出它在数组中分配的内存,从而产生不正确的结果。

    要保存这么大的整数,您必须指定a 才能拥有object 数据类型。例如:

    >>> np.left_shift(1, a.astype(object))
    array([2, 4, 1267650600228229401496703205376L], dtype=object)
    

    object 数组可以包含不同类型的混合,包括无限大小的 Python long/integer 值。然而,当使用object 数组时,同构数据类型 NumPy 数组的许多性能优势将丢失。

    【讨论】:

    • 一个小修正:python 中的整数(如int,但文档使用integer 在某种程度上作为int 的同义词)。 longs 按照您的描述行事。也就是说,这里的代码使用long 类型,如果你的文字对于int 来说太大,python 使用long。你的说法让我很困惑,我想让其他人看看docs.python.org/2/library/…
    • @kratenko - 谢谢,我应该更清楚地说明这一点。我想到了 Python 3,其中 long 类型已经消失(我现在看到问题被标记为 Python 2.7)。
    • 啊,我不知道 Python 3。我真的应该很快看看 3...
    • 说“long 类型在 Python 3 中消失了”可能会产生误导。在 Python 3 中,内置的 int 类型没有理论上的大小上限,因此基本上 long 已集成到 int 中。
    【解决方案2】:

    鉴于您创建的数组a,output 的元素将是整数。与 Python 本身不同,numpy darray 中的整数是固定大小的,具有定义的最大值和最小值。

    numpy 通过将移位取模整数的长度 64 位 (100 mod 64 == 36) 减少移位来达到给定的值 (2 ** 36)。

    【讨论】:

      【解决方案3】:

      这也是一个带有 64 位 Python 的issue,只是出现问题的整数更大。如果你运行a[2]=1L &lt;&lt; a[2],你会得到这个 Traceback :

      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      OverflowError: Python int too large to convert to C long
      

      所以正如回溯所说 Python int too large to convert to C long ,所以你需要将数组类型(实际上是 C 结构)更改为 python 对象:

      >>> a = np.array([1,2,100],dtype='O')
      >>> a[2]=1L << a[2]
      >>> a
      array([1, 2, 1267650600228229401496703205376L], dtype=object)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-01
        • 1970-01-01
        • 2020-01-10
        • 2019-04-04
        • 2018-04-19
        • 1970-01-01
        相关资源
        最近更新 更多