仅使用数学库即可对非常大的数求根

时间:2019-03-30 21:57:55

标签: python python-3.x

我想在Python3中计算一个非常大的立方根。

我已经尝试了下面的函数以及Python语法x ** (1 / n),但是它们都产生错误:

OverflowError: (34, 'Numerical result out of range')

我真的需要计算立方根才能解决密码学中的问题。除了数学,我不能使用任何其他模块。

二元搜索:

def find_invpow(x,n):
    """Finds the integer component of the n'th root of x,
    an integer such that y ** n <= x < (y + 1) ** n.
    """
    high = 1
    while high ** n < x:
        high *= 2
    low = high/2
    while low < high:
        mid = (low + high) // 2
        if low < mid and mid**n < x:
            low = mid
        elif high > mid and mid**n > x:
            high = mid
        else:
            return mid
    return mid + 1

导致错误的示例数字是:

num = 68057481137876648248241485864416419482650225630788641878663638907856305801266787545152598107424503316701887749720220603415974959561242770647206405075854693761748645436474693912889174270087450524201874301881144063774246565393171209785613106940896565658550145896382997905000280819929717554126192912435958881333015570058980589421883357999956417864406416064784421639624577881872069579492555550080496871742644626220376297153908107132546228975057498201139955163867578898758090850986317974370013630474749530052454762925065538161450906977368449669946613816

结果应该是这样(这是gmpy2所找到的内容,并且它是正确的-我已验证):

408280486712458018941011423246208684000839238529670746836313590220206147266723174123590947072617862777039701335841276608156219318663582175921048087813907313165314488199897222817084206

1 个答案:

答案 0 :(得分:3)

您的问题是您不严格遵守整数。 Python的整数是动态大小的,因此它们可以适合您想要的任何大小的值,而不会损失任何精度。但是浮点数固有地具有有限的精度。

当您进行low = high/2时,即使您不打算进行浮点计算,也可以进行计算。由于low是一个浮点数,因此mid也最终成为一个浮点数,并且当您测试mid的多维数据集时,浮点数最终会溢出并且会出现异常。

如果将low的第一个计算更改为使用//而不是/,则在整个计算过程中将坚持使用整数,并且不会出现溢出异常。只需进行一次更改,我就可以运行您的代码并获得您期望的结果:

>>> find_invpow(num, 3)
408280486712458018941011423246208684000839238529670746836313590220206147266723174123590947072617862777039701335841276608156219318663582175921048087813907313165314488199897222817084206