在Python中防止舍入为零

在Python中防止舍入为零,python,math,rounding,pi,Python,Math,Rounding,Pi,我有一个程序打算使用Chudnovsky算法来近似pi,但我的方程中的一个非常小的项一直被舍入为零 以下是算法: import math from decimal import * getcontext().prec = 100 pi = Decimal(0.0) C = Decimal(12/(math.sqrt(640320**3))) k = 0 x = Decimal(0.0) result = Decimal(0.0) sign = 1 while k<10: r =

我有一个程序打算使用Chudnovsky算法来近似pi,但我的方程中的一个非常小的项一直被舍入为零

以下是算法:

import math
from decimal import *
getcontext().prec = 100

pi = Decimal(0.0)
C = Decimal(12/(math.sqrt(640320**3)))
k = 0
x = Decimal(0.0)
result = Decimal(0.0)
sign = 1
while k<10:
    r = Decimal(math.factorial(6*k)/((math.factorial(k)**3)*math.factorial(3*k)))
    s = Decimal((13591409+545140134*k)/((640320**3)**k))
    x += Decimal(sign*r*s)
    sign = sign*(-1)
    k += 1
result = Decimal(C*x)
pi = Decimal(1/result)


print Decimal(pi)
导入数学
从十进制输入*
getcontext().prec=100
pi=十进制(0.0)
C=十进制(12/(数学sqrt(640320**3)))
k=0
x=十进制(0.0)
结果=十进制(0.0)
符号=1
当k时,尝试:

您正在执行的算术是本机python—通过允许Decimal对象执行除法,您应该消除错误

然后,在计算
r

几个注释时,也可以这样做

如果您使用的是Python2.x,
/
将返回一个整数结果。如果需要十进制结果,请至少先将一个边转换为十进制


math.sqrt()
仅返回约16位精度。由于C的值只能精确到16位,因此最终结果只能精确到16位。

我觉得“s”的问题是所有项都是整数,因此你在做整数数学。一个非常简单的解决方法是在分母中使用
3.0
。在计算中只需要一个浮点数就可以得到返回的浮点数。

如果您在Python 2.x中进行数学运算,您可能应该在每个模块中都使用这一行:

from __future__ import division
这将更改除法运算符的含义,以便在需要时返回一个浮点数以给出(更接近)精确的答案。如果
x
y
都是
int
s,则
x/y
的历史行为将返回
int
,这通常会迫使答案向下舍入

在Python这样鼓励duck类型的语言中,如果需要的话返回一个float通常被认为是处理除法的更好方法,因为您只需要担心数字的值,而不用担心不同类型的不同行为


在Python3中,这实际上是默认值,但由于旧程序依赖于除法运算符的历史行为,因此感觉这种更改太向后不兼容,无法在Python2中进行。这就是为什么您必须通过
\uuuuu future\uuuu
导入显式打开它。我建议在任何可能做任何数学运算的模块中添加该导入(或者,如果您有麻烦的话,只需添加任何模块)。你几乎永远不会因为它的存在而感到不安,但如果没有它,我不得不去寻找一些模糊的bug的原因。

这是什么版本的Python?你试过
s=float(13591409+545140134*k)/((640320**3)**k)
不知道为什么有人否决了这个问题。这是一个合理的问题,值得提问和回答。
来自未来进口部
您可能感兴趣。还有,我不相信《代码》中的汉克斯!这解决了问题。有没有更精确的平方根的方法?十进制实例有一个
sqrt()
方法,所以请尝试
C=12/(十进制(640320**3).sqrt())
谢谢casevh,他没有意识到这一点。
s = Decimal((13591409+545140134*k)) / Decimal(((640320**3)**k))
from __future__ import division