Python 仅使用数学库的非常大数字的立方根

Python 仅使用数学库的非常大数字的立方根,python,python-3.x,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,

我想计算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
结果应该是这样的(这是gmpy2发现的,并且是正确的-我已经验证过了):


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

当您执行
low=high/2
时,您将得到一个浮点计算,即使您不打算这样做。由于
low
是一个浮点数,
mid
最终也是一个浮点数,当您测试
mid
的多维数据集时,浮点数最终溢出,您会得到一个异常

如果将
的第一次计算更改为使用
/
而不是
/
,则在整个计算过程中都将使用整数,并且不会出现溢出异常。仅通过这一项更改,我就能够运行您的代码并获得您期望的结果:

>>> find_invpow(num, 3)
408280486712458018941011423246208684000839238529670746836313590220206147266723174123590947072617862777039701335841276608156219318663582175921048087813907313165314488199897222817084206

你能举一个导致溢出的数字的例子吗?@pault68057481137876648248241485864416419482650225630788641878663638907856305801266787545152598107424503316701887749720220603415974959561242770647206405075854693761748645436474693912889174270087450524201874301881144063774246565393171209785613106940896565658550145896382997905000280819929717554126192912435958881333015570058980589421883357999956417864406416064784421639624577881872069579492555550080496871742644626220376297153908107132546228975057498201139955163867578898758090850986317974370013630474749530052454762925065538161450906977368449669946613816
408280486712458018941011423246208684000839238529670746836313590220206147266723174123590947072617862777039701335841276608156219318663582175921048087813907313165314488199897222817084206
>>> find_invpow(num, 3)
408280486712458018941011423246208684000839238529670746836313590220206147266723174123590947072617862777039701335841276608156219318663582175921048087813907313165314488199897222817084206