Python和C的结果之间的差异

时间:2011-07-18 18:50:17

标签: python c

我在C(PI计算)中编写了非常简单的程序,我得到了这样的结果: 3.1406174152499528235728265546100601568468846380710601806640625

结果看起来不像正确的PI然后我在互联网上的Python中找到了代码我跑了它并得到了类似的东西: 3.1415926535897932384626433832795028841971693993751058209749 - 正确的PI。

然后我以完全相同的方式在C中实现了Python算法,我得到了这样的结果: 3.1406174152499528235728265546100601568468846380710601806640625

为什么结果形式Python和C来自同一算法是如此不同以及如何修复C代码以获得正确的结果?

Python代码:

from decimal import*

precision = 100

getcontext().prec = 100

a = 1
b = Decimal(1) / Decimal(2).sqrt()
t = Decimal(1) / Decimal(4)
p = 1
pi = 0
for x in range(0, precision):
    nextA = (a + b) / 2
    nextB = (a * b).sqrt()
    nextT = t - p * ((a - nextA) ** 2)
    nextP = 2 * p
    pi = ((a + b) ** 2) / (4 * t)
    a,b,t,p = nextA,nextB,nextT,nextP
print pi

C代码:

long double a = 1;
long double b = 1/sqrt(2);
long double t = 0.25;
long double p = 1;
long double an, bn, tn, pn, myPI;
long int x;
for(x = 0; x < 100; x++)
{
    an = (a + b) / 2;
    bn = sqrt(a * b);
    tn = t - p * ((a - an) * (a - an));
    pn = 2 * p;
    myPI = ((a + b) * (a + b)) / (4 * t);
    a = an; b = bn; t = tn; p = tn;
 }

printf("%.61Lf\n", myPI);
return 0;

3 个答案:

答案 0 :(得分:8)

问题是代码中的拼写错误,p = tn;应为p = pn;

注意:对于长双打,请使用sqrtl

更新:如果你在每次迭代后打印出pi的近似值,那么在第五次迭代之后它并没有变得更好,只有前20个数字是正确的。为了获得更高的精度,您需要更好的(不是内置的)数据类型。

答案 1 :(得分:6)

您要求的精度高于C浮点变量所能提供的精度。您需要使用任意精度算术而不是固定精度浮点。或者至少使用固定精度算术,其精度值大于您所需的计算精度。 Python代码将精度设置为100来实现此目的。


嗯,@ yi_H也在你的代码中发现了一个错误,但是即使你修复了这个错误,你也不会得到与C代码相同的精度,因为上面的原因。

答案 2 :(得分:0)

原因是浮点数(通常为80位)是C必须提供的最精确的数字数据类型,对于大多数实际计算来说,这已经足够了(OTOH)一个浮动,无论多大,都不能完全代表0.85,但除此之外。

Python有一个内置的大整数类型,它允许它代表任意大的整数(并且,在这个实现上捎带,任意精确的有理数)。通过使用这些,可以计算PI的近似值,它比浮子可以容纳的任何东西都精确得多。

如果你想要更高的精度,你需要找到一个逐个计算数字的算法,并在计算时将它们吐出来。