Python 3中数字大于10 ^ 2000的平方根

时间:2017-12-17 11:29:46

标签: python python-3.x

我想在Python中计算大于10 ^ 2000的数字的平方根。如果我将这个数字视为普通整数,我将总是得到这个结果:

Traceback (most recent call last):
  File "...", line 3, in <module>
    print( q*(0.5)  )
OverflowError: int too large to convert to float

我该如何解决这个问题?或者除了使用Python之外是否存在计算此平方根的可能性?

3 个答案:

答案 0 :(得分:7)

只需使用十进制模块:

>>> from decimal import *
>>> Decimal(10**2000).sqrt()
Decimal('1.000000000000000000000000000E+1000')
>>> Decimal(10**200000).sqrt()
Decimal('1.000000000000000000000000000E+100000')
>>> Decimal(15**35315).sqrt()
Decimal('6.782765081358674922386659760E+20766')

您还可以使用gmpy2 library

>>> import gmpy2
>>> n = gmpy2.mpz(99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999982920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000726067)
>>> gmpy2.get_context().precision=2048
>>> x = gmpy2.sqrt(n)

有用的链接:

  1. Decimal - Python Documentation

答案 1 :(得分:3)

通常的平方根方法在执行计算之前将参数转换为浮点值。如您所见,这对于非常大的整数不适用。

因此,使用一个旨在处理任意大整数的函数。这是一个,保证返回任何正整数的平方根的正确整数部分。此函数会删除结果的小数部分,这可能是您想要的,也可能不是。由于此函数使用迭代,因此它也比内置的平方根例程慢。 Decimal模块在比内置例程更大的整数上工作,但必须事先定义值的精度,因此它不适用于任意大的值。

import math

_1_50 = 1 << 50  # 2**50 == 1,125,899,906,842,624

def isqrt(x):
    """Return the integer part of the square root of x, even for very
    large integer values."""
    if x < 0:
        raise ValueError('square root not defined for negative numbers')
    if x < _1_50:
        return int(math.sqrt(x))  # use math's sqrt() for small parameters
    n = int(x)
    if n <= 1:
        return n  # handle sqrt(0)==0, sqrt(1)==1
    # Make a high initial estimate of the result (a little lower is slower!!!)
    r = 1 << ((n.bit_length() + 1) >> 1)
    while True:
        newr = (r + n // r) >> 1  # next estimate by Newton-Raphson
        if newr >= r:
            return r
        r = newr

答案 2 :(得分:0)

当使用库 math 中的 sqrt 时,在对它进行平方根之前,它会将值转换为浮点数。

如果我们手动尝试将 10**2000 转换为浮点数,也会触发错误

>>> float(10**2000)
---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
<ipython-input-14-6ac81f63106d> in <module>
----> 1 math.sqrt(10**2000)

OverflowError: int too large to convert to float

如果我们说的是一个大数,但平方等于或小于 308,那么 Decimal 模块将执行如下工作

>>> from decimal import Decimal
>>> Decimal(math.sqrt(10**308))
Decimal('10000000000000000369475456880582265409809179829842688451922778552150543659347219597216513109705408327446511753687232667314337003349573404171046192448274432')

然而,由于数字是方格比308大得多,在这种情况下,2000,你必须这样做

>>> from decimal import Decimal
>>> Decimal(10**2000).sqrt()
Decimal('1.000000000000000000000000000E+1000')

如果尝试将 Decimal(10**2000) 转换为浮点数,让我们看看输出

>>> float(Decimal(10**2000))
inf

在处理阶乘时也可能使用小数模块,因为它们往往会很快变大。