python中的精度高达50位小数

时间:2013-12-01 16:22:10

标签: python precision floating-point-precision double-precision

我正在尝试编码以查找内部soddy圈的半径,代码运行正常但我没有得到所需的精度,我希望将答案截断为50位数 请建议我如何获得更精确的计算 我应该如何获得50位数的精度

import math
t=input()
while t>0:
    t-=1
    r1,r2,r3=map(int,raw_input().split())
    k1=1.0/r1
    k2=1.0/r2
    k3=1.0/r3
    k4=k1+k2+k3+2*math.sqrt(k1*k2+k2*k3+k3*k1)
    r4=1.0/k4
    print r4

2 个答案:

答案 0 :(得分:3)

使用decimal模块。将您正在使用的所有变量存储为decimal.Decimal个对象。

更新的代码:

from decimal import *
import math
context = Context(prec=1000)
setcontext(context)
t=input()
while t>0:
    t-=1
    r1,r2,r3=map(Decimal,raw_input().split())
    k1=Decimal(1.0)/Decimal(r1)
    k2=Decimal(1.0)/Decimal(r2)
    k3=Decimal(1.0)/Decimal(r3)
    k4=k1+k2+k3+2*(k1*k2+k2*k3+k3*k1).sqrt()
    r4=Decimal(1.0)/Decimal(k4)
    print r4

答案 1 :(得分:2)

如果更多迭代应该产生更好的结果,那么你可以忽略输入t参数并迭代直到结果收敛于当前精度:

import decimal

#NOTE: separate user input from the algorithm
#      no input inside `radius()` function
def radius(r1, r2, r3):
    with decimal.localcontext() as ctx:
        ctx.prec += 2 # increase precision for intermediate calculations
        prev = None # previous value
        k1, k2, k3 = [1 / decimal.Decimal(r) for r in [r1, r2, r3]]
        while True: 
            # change some parameters to simulate converging algorithm
            #NOTE: you don't need to wrap anything using `Decimal()`
            k1 = k1 + k2 + k3 + 2*(k1*k2 + k2*k3 + k3*k1).sqrt()
            r = 1 / k1
            if prev == r: # compare using enhanced precision
                break
            prev = r # save previous value
    return +r # `+` applies current precision

decimal.getcontext().prec = 50 # set desired precision
print(radius(*map(int, raw_input().split())))

有关演示此技术的工作示例,请参阅计算Pi最多100位的Gauss-Legendre Algorithm in python