1

我试图使用numpy.divmod非常大的整数,但我注意到一个奇怪的行为。在大约2**63 ~ 1e19(这应该是intpython 3.5+ 中通常的内存表示的限制)时,会发生这种情况:

from numpy import divmod

test = 10**6
for i in range(15,25):
  x = 10**i
  print(i, divmod(x, test))

15 (1000000000, 0)
16 (10000000000, 0)
17 (100000000000, 0)
18 (1000000000000, 0)
19 (10000000000000.0, 0.0)
20 ((100000000000000, 0), None)
21 ((1000000000000000, 0), None)
22 ((10000000000000000, 0), None)
23 ((100000000000000000, 0), None)
24 ((1000000000000000000, 0), None)

不知何故,商和余数可以正常工作,直到2**63,然后有一些不同的东西。

我的猜测是int表示是“矢量化的”(即BigInt在 Scala 中,作为 的小端序SeqLong。但是,作为 的结果,我期望divmod(array, test)有一对数组:商数组和余数数组。

我对这个功能一无所知。内置 divmod 不会发生这种情况(一切都按预期工作)

为什么会这样?它与int内部表示有关吗?

详细信息:numpy 版本 1.13.1,python 3.6

4

1 回答 1

2

问题是np.divmod将参数转换为数组,发生的事情非常简单:

>>> np.array(10**19)
array(10000000000000000000, dtype=uint64)
>>> np.array(10**20)
array(100000000000000000000, dtype=object)

你会得到一个with的object数组,在其他情况下它将是一个“真正的 NumPy 数组”。10**ii > 19

object而且,确实,数组的行为似乎很奇怪np.divmod

>>> np.divmod(np.array(10**5, dtype=object), 10)   # smaller value but object array
((10000, 0), None)

我猜在这种情况下,普通的Python内置函数divmod会计算第一个返回的元素,并且所有剩余的项目都被填充,None因为它委托给 Pythons 函数。

请注意,object数组的行为通常与本机 dtype 数组不同。它们要慢得多,并且经常委托给 Python 函数(这通常是导致不同结果的原因)。

于 2017-09-21T11:17:57.537 回答