Python numpy大整数失败

Python numpy大整数失败,python,numpy,biginteger,Python,Numpy,Biginteger,我最近在处理一些项目Euler问题 最小倍数 问题5 2520是最小的数字,可以被1到10之间的每一个数字除,没有任何余数 能被1到20的所有数整除的最小正数是多少 我写了我的代码,效果很好 def factor_finder(n, j=2): factor_list = [] if n == 2: return [2] elif n == 3: return [3] else: while n >= j

我最近在处理一些项目Euler问题

最小倍数 问题5 2520是最小的数字,可以被1到10之间的每一个数字除,没有任何余数

能被1到20的所有数整除的最小正数是多少

我写了我的代码,效果很好

def factor_finder(n, j=2):

    factor_list = []

    if n == 2:
        return [2]
    elif n == 3:
        return [3]
    else:
        while n >= j * 2:
            while n % j == 0:
                n = int(n / j)
                factor_list.append(j)
            j += 1

    if n > 1:
        factor_list.append(n)

    return factor_list



def smallest_multiples(n):

    from functools import reduce

    factor_list = []
    final_list = []

    for i in range(2, n + 1):
        factor_list += factor_finder(i)
    # print(factor_list)

    for i in set(factor_list):
        l1 = []
        l2 = []
        for j in factor_list:
            if j == i:
                l1.append(j)
            else:
                if len(l1) > len(l2):
                    l2 = l1
                    l1 = []
                else:
                    l1 = []
        # print(l2)
        final_list += l2
    # print(final_list)

    return (
        np.array(final_list).cumprod()[-1],
        reduce((lambda x, y: x * y), final_list),
    )
结果是:

%时间

最小单位倍数(1000)

CPU时间:用户5µs,系统:0 ns,总计:5µs 壁时间:32.4µs

(-4008056434385126912, 712886527466509305316638415571427292066835886188589304045200199115432408758111149947644415191387158691171781701957525651298026406762100925146587100430513107268626814320019660997486274593718834370501543445252373974529896314567498212823695623282379401106880926231770886197954079124775455804932647573782992335275179673524804246363805113703433121478174685088453485678021880753324992199567205692029099390891687487672697950931603520000)


我的问题是为什么numpy.cumprod()无法获得正确的数字。我以为numpy就是数字工具。谁能给我一些想法吗?

数值分析不是数论。正确性不是唯一的目标,但必须与效率进行权衡。任意精度的数字(如大整数)速度较慢,因此numpy默认使用固定长度的整数。当它们变得太大时,就会溢出。您可以指示numpy使用任意精度的整数,但会损失很多速度:

np.arange(1, 100).prod() # fast but wrong
# 0
np.arange(1, 100, dtype=object).prod() # slow but correct
# 933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000

数值分析不是数论。正确性不是唯一的目标,但必须与效率进行权衡。任意精度的数字(如大整数)速度较慢,因此numpy默认使用固定长度的整数。当它们变得太大时,就会溢出。您可以指示numpy使用任意精度的整数,但会损失很多速度:

np.arange(1, 100).prod() # fast but wrong
# 0
np.arange(1, 100, dtype=object).prod() # slow but correct
# 933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000

问题是,这个数字的大小意味着它不再可以用Python中的int表示。如果您查看,您将看到ints最大值约为19位(即63位+符号位的2^63),然后进入溢出。Numpy是基于C语言的,它使用固定精度进行更快的计算,但需要权衡的是,它受到64位整数的限制,并且会溢出。numpy中的一些函数甚至通过转换为浮点数来进行计算(可以容纳更多的数字)来防止这种情况

如果您告诉numpy使用“object”作为数据类型,会有很大的时间损失,但它会让您使用Python中使用的任意精度。对于您的代码,它看起来像:

return (
    np.cumprod(final_list, dtype="object")[-1],
    reduce((lambda x, y: x * y), final_list),
)

问题是,这个数字达到了一个大小,这意味着它不再可以用Python中的int来表示。如果您查看,您将看到ints最大值约为19位(即63位+符号位的2^63),然后进入溢出。Numpy是基于C语言的,它使用固定精度进行更快的计算,但需要权衡的是,它受到64位整数的限制,并且会溢出。numpy中的一些函数甚至通过转换为浮点数来进行计算(可以容纳更多的数字)来防止这种情况

如果您告诉numpy使用“object”作为数据类型,会有很大的时间损失,但它会让您使用Python中使用的任意精度。对于您的代码,它看起来像:

return (
    np.cumprod(final_list, dtype="object")[-1],
    reduce((lambda x, y: x * y), final_list),
)

THX,所以numpy仍然是数字工具。我现在感觉好多了。THX,所以numpy仍然是数字工具。我现在感觉好多了。