Python 如何计算一个非常大的整数的第n个根

Python 如何计算一个非常大的整数的第n个根,python,math,nth-root,Python,Math,Nth Root,我需要一种在Python中计算长整数的第n个根的方法 我尝试了pow(m,1.0/n),但不起作用: 溢出错误:长整型太大,无法转换为浮点型 有什么想法吗 我所说的长整数是指真正的长整数,比如: 11968003966030964356885611480343088317234645046739251 196093144141045683463085291115677488411620264826942334897996389 4850462628472657692808832376494611

我需要一种在Python中计算长整数的第n个根的方法

我尝试了
pow(m,1.0/n)
,但不起作用:


溢出错误:长整型太大,无法转换为浮点型

有什么想法吗

我所说的长整数是指真正的长整数,比如:

11968003966030964356885611480343088317234645046739251 196093144141045683463085291115677488411620264826942334897996389 485046262847265769280883237649461122479734279424416861834396522 819159219215308460065265520143082728303864638821979329804885526 557893649662037092457130509980883789368448042961108430809620626 059287437887495827369474189818588006905358793385574832590121472 680866521970802708379837148646191567765584039175249171110593159 305029014037881475265618958103073425958633163441030267478942720 703134493880117805010891574606323700178176718412858948243785754 898788359757528163558061136758276299059029113119763557411729353 915848889261125855717014320045292143759177464380434854573300054 940683350937992500211758727939459249163046465047204851616590276 724564411037216844005877918224201569391107769029955591465502737 961776799311859881060956465198859727495735498887960494256488224 613682478900505821893815926193600121890632


尝试将指数转换为浮点数,因为/在Python中的默认行为是整数除法


n**(1/float(3))

尝试将指数转换为浮点数,因为Python中的默认行为是整数除法


n**(1/float(3))

在早期版本的Python中,
1/3
等于0。在Python 3.0中,
1/3
等于0.33333(并且
1//3
等于0)


因此,要么将代码更改为使用
1/3.0
,要么切换到Python 3.0。

在较早版本的Python中,
1/3
等于0。在Python 3.0中,
1/3
等于0.33333(并且
1//3
等于0)

因此,您可以将代码更改为使用
1/3.0
或切换到Python 3.0。

是一个C编码的Python扩展模块,它包装了GMP库,为Python代码提供快速多精度算法(整数、有理数和浮点数)、随机数生成、高级数论函数等

包括一个
root
函数:

x、 root(n):返回一个2元素元组(y,m),因此y是 (可能被截断)x的第n个根;m、 一个普通的Python int, 如果根是精确的(x==y**n),则为1,否则为0。n必须是普通的 Python int,>=0

例如,第20根:

>>> import gmpy
>>> i0=11968003966030964356885611480383408833172346450467339251 
>>> m0=gmpy.mpz(i0)
>>> m0
mpz(11968003966030964356885611480383408833172346450467339251L)
>>> m0.root(20)
(mpz(567), 0)
是一个C编码的Python扩展模块,它封装了GMP库,为Python代码提供快速多精度算法(整数、有理数和浮点)、随机数生成、高级数字理论函数等

包括一个
root
函数:

x、 root(n):返回一个2元素元组(y,m),因此y是 (可能被截断)x的第n个根;m、 一个普通的Python int, 如果根是精确的(x==y**n),则为1,否则为0。n必须是普通的 Python int,>=0

例如,第20根:

>>> import gmpy
>>> i0=11968003966030964356885611480383408833172346450467339251 
>>> m0=gmpy.mpz(i0)
>>> m0
mpz(11968003966030964356885611480383408833172346450467339251L)
>>> m0.root(20)
(mpz(567), 0)

如果这个数字真的很大。您可以使用二进制搜索

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
def find_invpow(x,n):
“”“查找x的第n个根的整数分量,

一个整数,比如y**n,如果它是一个非常大的数字。你可以使用二进制搜索

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
def find_invpow(x,n):
“”“查找x的第n个根的整数分量,

一个整数,比如y**n如果你不特别担心精度,你可以把它转换成一个sting,切掉一些数字,使用指数函数,然后将结果乘以切掉多少的根

例如,32123大约等于32*1000,立方根大约等于32*1000的立方根。后者可以通过0的数量除以3来计算


这就避免了使用扩展模块。

如果你不特别担心精度,你可以将它转换成一个sting,切掉一些数字,使用指数函数,然后将结果乘以切掉多少的根

例如,32123大约等于32*1000,立方根大约等于32*1000的立方根。后者可以通过0的数量除以3来计算

这就避免了使用扩展模块。

哦,对于这么大的数字,您可以使用十进制模块

ns:您的数字是一个字符串

ns = "11968003966030964356885611480383408833172346450467339251196093144141045683463085291115677488411620264826942334897996389485046262847265769280883237649461122479734279424416861834396522819159219215308460065265520143082728303864638821979329804885526557893649662037092457130509980883789368448042961108430809620626059287437887495827369474189818588006905358793385574832590121472680866521970802708379837148646191567765584039175249171110593159305029014037881475265618958103073425958633163441030267478942720703134493880117805010891574606323700178176718412858948243785754898788359757528163558061136758276299059029113119763557411729353915848889261125855717014320045292143759177464380434854573300054940683350937992500211758727939459249163046465047204851616590276724564411037216844005877918224201569391107769029955591465502737961776799311859881060956465198859727495735498887960494256488224613682478900505821893815926193600121890632"
from decimal import Decimal
d = Decimal(ns)
one_third = Decimal("0.3333333333333333")
print d ** one_third
答案是:2.287391878618402702753613056E+305

TZ指出这是不准确的。。。他是对的。这是我的测试

from decimal import Decimal

def nth_root(num_decimal, n_integer):
    exponent = Decimal("1.0") / Decimal(n_integer)
    return num_decimal ** exponent

def test():
    ns = "11968003966030964356885611480383408833172346450467339251196093144141045683463085291115677488411620264826942334897996389485046262847265769280883237649461122479734279424416861834396522819159219215308460065265520143082728303864638821979329804885526557893649662037092457130509980883789368448042961108430809620626059287437887495827369474189818588006905358793385574832590121472680866521970802708379837148646191567765584039175249171110593159305029014037881475265618958103073425958633163441030267478942720703134493880117805010891574606323700178176718412858948243785754898788359757528163558061136758276299059029113119763557411729353915848889261125855717014320045292143759177464380434854573300054940683350937992500211758727939459249163046465047204851616590276724564411037216844005877918224201569391107769029955591465502737961776799311859881060956465198859727495735498887960494256488224613682478900505821893815926193600121890632"
    nd = Decimal(ns)
    cube_root = nth_root(nd, 3)
    print (cube_root ** Decimal("3.0")) - nd

if __name__ == "__main__":
    test()
大约是10**891

哦,对于这么大的数字,你可以使用十进制模块

ns:您的数字是一个字符串

ns = "11968003966030964356885611480383408833172346450467339251196093144141045683463085291115677488411620264826942334897996389485046262847265769280883237649461122479734279424416861834396522819159219215308460065265520143082728303864638821979329804885526557893649662037092457130509980883789368448042961108430809620626059287437887495827369474189818588006905358793385574832590121472680866521970802708379837148646191567765584039175249171110593159305029014037881475265618958103073425958633163441030267478942720703134493880117805010891574606323700178176718412858948243785754898788359757528163558061136758276299059029113119763557411729353915848889261125855717014320045292143759177464380434854573300054940683350937992500211758727939459249163046465047204851616590276724564411037216844005877918224201569391107769029955591465502737961776799311859881060956465198859727495735498887960494256488224613682478900505821893815926193600121890632"
from decimal import Decimal
d = Decimal(ns)
one_third = Decimal("0.3333333333333333")
print d ** one_third
答案是:2.287391878618402702753613056E+305

TZ指出这是不准确的。。。他是对的。这是我的测试

from decimal import Decimal

def nth_root(num_decimal, n_integer):
    exponent = Decimal("1.0") / Decimal(n_integer)
    return num_decimal ** exponent

def test():
    ns = "11968003966030964356885611480383408833172346450467339251196093144141045683463085291115677488411620264826942334897996389485046262847265769280883237649461122479734279424416861834396522819159219215308460065265520143082728303864638821979329804885526557893649662037092457130509980883789368448042961108430809620626059287437887495827369474189818588006905358793385574832590121472680866521970802708379837148646191567765584039175249171110593159305029014037881475265618958103073425958633163441030267478942720703134493880117805010891574606323700178176718412858948243785754898788359757528163558061136758276299059029113119763557411729353915848889261125855717014320045292143759177464380434854573300054940683350937992500211758727939459249163046465047204851616590276724564411037216844005877918224201569391107769029955591465502737961776799311859881060956465198859727495735498887960494256488224613682478900505821893815926193600121890632"
    nd = Decimal(ns)
    cube_root = nth_root(nd, 3)
    print (cube_root ** Decimal("3.0")) - nd

if __name__ == "__main__":
    test()

大约10**891关闭,可能是出于好奇:

这可能是Maple用于实际查找大数的第n个根的技术


假设
x^n-11968003….=0 mod p
,然后从那里开始…

可能是出于好奇:

这可能是Maple用于实际查找大数的第n个根的技术


假设
x^n-11968003….=0 mod p
,然后从那里开始…

您可以通过避免while循环,将low设置为10**(len(str(x))/n,将high设置为low*10,从而使其运行稍微更快。可能更好的方法是将len(str(x))替换为按位长度并使用位移位。根据我的测试,我估计第一次的加速比为5%,第二次的加速比为25%。如果INT足够大,这可能很重要(加速比可能会有所不同)。如果不仔细测试,就不要相信我的代码。我做了一些基本测试,但可能错过了一个边缘案例。肌萎缩侧索硬化
with decimal.localcontext() as context:
    context.prec = 50
    print(cube_root(42))