I wrote very simple program in C (PI computation) and I got result like this: 3.1406174152499528235728265546100601568468846380710601806640625
Result doesn't look like proper PI then I found code in Python on internet I ran it and got something like that: 3.1415926535897932384626433832795028841971693993751058209749 - Proper PI.
Then I implemented Python algorithm in C with exactly the same way and I got result like that: 3.1406174152499528235728265546100601568468846380710601806640625
Why results form Python and C from the same algorithm are so different and how to fix C code to get right result ??
Python code:
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 code:
l开发者_开发百科ong 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;
The problem is a typo in your code, p = tn;
should be p = pn;
.
Note: for long doubles use sqrtl
.
Update: if you print out the approximation for pi after each iteration it doesn't get any better after the fifth iteration and only the first 20 digits are correct. for more precision you need better (not builtin) data types.
You are asking for more precision than your C floating point variables can provide. You need to use arbitrary precision arithmetic rather than fixed precision floating point. Or at the very least use fixed precision arithmetic with a precision value greater than your desired calculation precision. The Python code sets the precision to 100 to achieve this.
Well, @yi_H also found a bug in your code but even when you fix that you won't get the same precision from your C code as from your Python code for the reasons above.
The reason is that floating-point numbers (typically 80 bits total) are the most precise numeric data type C has to offer out-of-the-box, and for most real-world computations, that's more than enough (OTOH, a float, no matter how large, cannot exactly represent 0.85 for example, but that aside).
Python has a built-in big-integer type which allows it to represent arbitrarily large integers (and, piggy-backing on this implementation, arbitrarily precise rational numbers). By using these, approximations of PI can be calculated that are far more precise than anything a float can hold.
If you want even more precision, you'll need to find an algorithm that calculates digits one by one, and have it spit them out while calculating.
精彩评论