|
贴个PI 程序,看看吧?
太长了,局部。
pi_c50/ 0040775 0000764 0000764 00000000000 07443503674 010567 5 ustar dara dara pi_c50/pi_c50.c 0100664 0000764 0000764 00000017421 07443503674 012014 0 ustar dara dara /*----------------------------------------------------------------------
program to calculate pi, version 5.0
This uses Klingenstierna's formula. The atan(1/10) term is
handled with fast shifts, and the atan(1/515) term uses a
sophisticated check to prevent overflow when dividing by 515^2
(inspired by Adrian Umpleby). Where
remainder*10000 + term[x]
can overflow, use instead
(remainder - 53045 + 53045)*10000 + term[x]
Upon dividing by 515^2,
((remainder - 53045)*10000 + term[x])/265225 + 2000
and the quantity in parentheses is guaranteed to be less than a long
integer in size. It turns out that this is faster than using an unsigned
long remainder, and much faster than using 64 bit arithmetic. Execution
time is now down to 4.73 seconds for 5000 digits on my 486 66MHz computer,
a 2% speed boost over version 4.8, and easily the fastest pi calculator
I've seen that adds up series.
If you have gcc, compile with the -O3 optimization option. This is rather
important, since among other things the remainder from integer division
is automatically used instead of being computed all over again, and this
makes the whole thing run 30% faster.
Special thanks to Randall Williams, who crunched out the first C version
of this program and much of whose code is still here, and to Bill Lanam,
who pointed out that I didn't need assembly after all. Thanks to Bob
Farrington, Larry Shultis, and Adrian Umpleby for great ideas, and to
Gordon Spinks for making it more portable. -jasonp@isr.umd.edu
-----------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void printout(void);
void atan10(long denom);
void atan239(long denom);
void atan515(long denom);
int *term;
long *sum, firstword, words;
int main(int argc, char *argv[]){
int remainder;
long denom, digits = 0, x;
clock_t end,start;
if(argc != 2){
printf("nusage: pi50 NumberOfDigits > OutputFilenn");
}
else{
digits = atol( argv[1] );
}
if( digits<50 || digits>210000 ){
printf("Setting default to 50 digits.n");
digits=50;
}
/* Allocate array space and initialize */
words = digits / 4 + 3;
sum = (long *)calloc( words + 2, sizeof(long) );
term = (int *)calloc( words + 2, sizeof(int) );
if( sum == NULL || term == NULL ) {
printf("Memory allocation failed. Try fewer digits.n");
exit(EXIT_FAILURE);
}
/* ----- 32*atan(1/10) -------*/
start = clock();
denom = 3; sum[1] = 32;
for (firstword=2; firstword<=words; firstword++) {
atan10(denom);
denom += 4;
}
/* ----- -4*atan(1/239) ------- */
firstword = 2; denom = 3; remainder = 40;
for( x=2; x<=words; x++){
digits = (long)remainder * 10000;
term[x] = digits / 239; /* first term */
remainder = digits % 239;
sum[x] -= term[x];
}
while( firstword<words ){
atan239(denom);
denom += 4;
}
/* ----- -16*atan(1/515) ------- */
firstword = 2; denom = 3; remainder = 160;
for( x=2; x<=words; x++){
digits = (long)remainder * 10000;
term[x] = digits / 515; /* first term */
remainder = digits % 515;
sum[x] -= term[x];
} |
|