如何将数组中的每个元素与一个大数相乘而不产生溢出错误:Python int太大而无法转换为C long?

2024-05-16 20:25:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我在写一个程序,我想用一个大数(1.692287392646066e+41)乘以一个数组中的每个数,我这样做:

x = array([ 16,  18,  19,  15,  27,  26,  13,  34,  38,  36,  43,  42,  48,
    50,  55,  57,  70,  67,  65,  85,  99,  94,  90, 112, 126, 130,
   142, 120])
weight = 1.692287392646066e+41

x[:] = [i*weight for i in x]

但后来我收到了错误“overflowerr:Python int太大,无法转换为C long”。奇怪的是,将for循环外的数字相乘似乎有效:

^{pr2}$

我的问题是,既然我事先不知道数组有多长,有没有什么方法可以在for循环中执行此操作?(我知道它有一排。)


Tags: 方法in程序for错误数字数组array
3条回答

python中而不是在numpy中进行乘法是没有意义的。不仅numpy更快,而且效果更好。在

您要做的是创建一个python list,然后它试图将其复制到numpy array元素中。在

相反,只要使用

x = x * weight

你很好。在

EOL怀疑这是否有效,所以我在电脑上做了些什么:

^{pr2}$

请注意,numpy.ndarray实例x一旦创建,将为存储的基础数据分配一个唯一的类型。这与Python本机列表非常不同,它类似于一个数组,其中包含对任意、duck类型的Python对象的引用。在

随后对底层数组数据的就地修改(在本例中是切片分配,即实际调用__setitem__方法的语法糖)将尝试将值强制转换到存储类型中。在本例中,数组x有整数,但在赋值的RHS处计算的浮点值太大,无法转换为整数,从而导致整数溢出。在

如果你用一个合适的float类型来创建数组,它本来可以工作的。在pseudo Python中:

# Type for the storage of x explicitly set when creating it.
x = numpy.array([ whatever integer literals ... ], dtype=numpy.float64)
# Assignment succeeds.
x[:] = [ some list of floats ... ]

下面带有shallow copy(s[:])的命令将为您创建一个s的视图,该视图的元素类型为int,因此在赋值之后,它尝试将[i*weight for i in s]创建的元素分配给int容器,但由于结果是C long,因此会引发以下错误:

OverflowError: Python int too large to convert to C long

如果您只使用[i*weight for i in s],您也将看到结果:

^{pr2}$

相反,您可以直接多重:

>>> s = s*weight
>>> s
array([  2.70765983e+42,   3.04611731e+42,   3.21534605e+42,
         2.53843109e+42,   4.56917596e+42,   4.39994722e+42,
         2.19997361e+42,   5.75377713e+42,   6.43069209e+42,
         6.09223461e+42,   7.27683579e+42,   7.10760705e+42,
         8.12297948e+42,   8.46143696e+42,   9.30758066e+42,
         9.64603814e+42,   1.18460117e+43,   1.13383255e+43,
         1.09998681e+43,   1.43844428e+43,   1.67536452e+43,
         1.59075015e+43,   1.52305865e+43,   1.89536188e+43,
         2.13228211e+43,   2.19997361e+43,   2.40304810e+43,
         2.03074487e+43])

相关问题 更多 >