在python中使用math模块的sqrt函数处理长数字[duplicate]

yhqotfr8  于 2022-12-25  发布在  Python
关注(0)|答案(4)|浏览(142)
    • 此问题在此处已有答案**:

Integer square root in python(15个答案)
17小时前关门了。
我在python中处理200位数的数字。当使用math. sqrt(n)求一个数字的平方根时,我得到了一个错误的答案。

In[1]: n=9999999999999999999999999999999999999999999999999999999999999999999999
       999999999999999999999999998292000000000000000000000000000000000000000000
       0000000000000000000000000000000000000000000000000000726067

In[2]: x=int(math.sqrt(n))

In[3]: x
Out[1]: 10000000000000000159028911097599180468360808563945281389781327
        557747838772170381060813469985856815104L

In[4]: x*x
Out[2]: 1000000000000000031805782219519836346574107361670094060730052612580
        0264077231077619856175974095677538298443892851483731336069235827852
        3336313169161345893842466001164011496325176947445331439002442530816L

In[5]: math.sqrt(n)
Out[3]: 1e+100

由于x * x(201位数)大于n(200位数),x的值将大于预期值,这里发生了什么?我在这里犯了什么错误吗?我还能如何找到非常大的数的根?

hl0ma9xz

hl0ma9xz1#

使用the decimal module

import decimal
D = decimal.Decimal
n = D(99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999982920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000726067)

with decimal.localcontext() as ctx:
    ctx.prec = 300
    x = n.sqrt()
    print(x)
    print(x*x)
    print(n-x*x)

收益率

9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999145.99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999983754999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998612677

99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999982920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000726067.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

0E-100
fnvucqvd

fnvucqvd2#

math.sqrt返回IEEE-754 64位结果,大约为17位,还有其他库可以处理高精度值,除了上面提到的decimalmpmath库之外,我还维护gmpy2库(https://code.google.com/p/gmpy/)。

>>> import gmpy2
>>> n=gmpy2.mpz(99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999982920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000726067)
>>> gmpy2.get_context().precision=2048
>>> x=gmpy2.sqrt(n)
>>> x*x
mpfr('99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999982920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000726067.0',2048)
>>>

gmpy2库还可以返回整数平方根(isqrt)或快速检查整数是否为精确平方(is_square)。

o2gm4chl

o2gm4chl3#

这是一个整数平方根程序,使用了我不久前写的Hero方法,初始近似值是输入值位长的一半,所以收敛速度很快,但是,我还没有计时,看看在Python中它是否比使用更简单的初始近似值更快。

#! /usr/bin/env python

''' Long integer square roots. Newton's method.

    Written by PM 2Ring. Adapted from C to Python 2008.10.19
'''

import sys

def root(m):
    # Get initial approximation
    n, a, k = m, 1, 0
    while n > a:
        n >>= 1
        a <<= 1
        k += 1
        #print k, ':', n, a

    # Go back one step & average
    a = n + (a>>2)
    #print a

    # Apply Newton's method
    while k:
        a = (a + m // a) >> 1
        k >>= 1
        #print k, ':', a
    return a

def main():
    m = len(sys.argv) > 1 and int(sys.argv[1]) or 2*10L**100
    print "The Square Root of", m
    print root(m)

if __name__ == '__main__':
    main()
vdzxcuhz

vdzxcuhz4#

你可以用python3 Num类(包num7)找到非常大的数的根,如下所示:

#square root of very large numbers
from num7 import Num

n = Num('99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999982920000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000726067.0')
r1 = n.sqrt()
print('n=>', n)
print('DIGITS', n.len()) #DIGITS (200, 0)
print('r1=>', r1)#9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999145.99999999999999999999999999999999999999999999999999999999999999999999999999999999
print('DIGITS', r1.len())#DIGITS (100, 80)
print('--'*20) 

x2 = r1*r1     
print('x2=>', x2)#99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999982919999999999999999999999999999999999999999999999999999999999999999999999999999999800000000000000729316.0000000000000000000000000000000000000000000000000000000000000000000000000000170800000000000000000000000000000000000000000000000000000000000000000000000000000001
print('DIGITS', x2.len())#DIGITS (200, 160)
print('--'*20)
print('difference n-x2=>', n-x2) #199999999999999996750.9999999999999999999999999999999999999999999999999999999999999999999999999999829199999999999999999999999999999999999999999999999999999999999999999999999999999999

相关问题