Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* CE PROGRAMME CALCULE JUSQU'A 150000 (OU 644690 SUIVANT TYPE DE MACHINE)
- DECIMALES DE PI A L'AIDE DE LA FORMULE DE MACHIN:
- PI=16*ARCTG(1/5)-4*ARCTG(1/239)
- CHAQUE ARCTG EST LA SOMME DES Vn AVEC
- Vn=(-1)^n/((2*n+1)*X^(2*n+1))
- X VALANT RESPECTIVEMENT 5 ET 239. CHAQUE TERME Vn EST OBTENU PAR
- RECURRENCE SUIVANT LES FORMULES:
- V0 = 1/X
- Vn+1 = [(-1)*(2*n+1)/((2*n+3)*X*X)]*Vn.
- LES CALCULS SONT FAITS EN MULTIPRECISION SUR 32 BITS (RESP. 64 BITS)
- LA CONTRAINTE DUE A LA LIMITATION DES ENTIERS SUR 32 BITS (RESP. 64
- BITS) FAIT QUE LES CALCULS DES DEUX ARCTG SONT FAITS DIFFEREMMENT
- DANS UN SOUCI D'OPTIMISATION.
- LES CALCULS SONT FAITS SUR DES ENTIERS SIGNES, DONC ON UTILISE
- LES 31 BITS (RESP. 63 BITS) DE CES NOMBRES. LA BASE DE NUMERATION
- UTILISEE EST 1 000 000 (RESP. 10^15) JUSQU'A 1500 (RESP. 6649)
- DECIMALES, 100 000 (RESP. 10^14) JUSQU'A 15 000 (RESP. 66471) ET
- 10 000 (RESP. 10^13) JUSQU'A 150 000 (RESP. 644690) DECIMALES CECI
- POUR EVITER DE DEPASSER LES 31 BITS (RESP. 63 BITS) IMPOSES.
- IL Y A DONC UNE BAISSE DE PERFORMANCE AU DELA DE 1500 (RESP. 6649)
- DECIMALES.
- SUR UNE MACHINE A MOTS DE 64 BITS L'ALGORITHME EST PLUS PERFORMANT
- CAR ON UTILISE UNE BASE DE NUMERATION BEAUCOUP PLUS GRANDE.
- A LA COMPILATION IL FAUT DONC CHOISIR SON TYPE DE MACHINE:
- cc -DS64BITS -o pim2 pim2.c POUR MACHINE A MOTS DE 64 BITS
- cc -DS32BITS -o pim2 pim2.c POUR MACHINE A MOTS DE 32 BITS
- SI L'ON VEUT TRAVAILLER AVEC DES MOTS DE 32 BITS SUR UNE MACHINE
- A MOTS DE 64 BITS IL FAUT UTILISER L'OPTION DE COMPILATION:
- cc -DS32BITSFORCE -o pim2 pim2.c SUR LA MACHINE A MOTS DE 64 BITS.
- CELA PERMET DE COMPARER LES PERFORMANCES DES MACHINES AVEC LE
- MEME ALGORITHME.
- Usage: pim2 [-2] [entier]
- -2: sortie des decimales en base 2.
- entier: nombre de decimales maxi.
- DANS LE CAS D'UNE SORTIE DES DECIMALES EN BASE 2, LA PERFORMANCE
- DU PROGRAMME EST MOINS BONNE CAR LE CALCUL EST TOUJOURS FAIT EN
- BASE 10 MAIS ON FAIT ENSUITE UNE CONVERSION EN BASE 2 QUI EST PLUS
- LOURDE QU'UNE CONVERSION EN BASE 10. AVOIR PI EN BASE 2 N'A D'INTERET
- QUE POUR OBTENIR UNE SUITE DE 0 ET DE 1 CONSIDERES COMME ALEATOIRE.
- fichier pim2.c Andre' Brouty (CNRS / ENST de Bretagne) decembre 1987
- portage pour machine a mots de 64 bits: decembre 1995
- portage pour sortie des decimales en base 2: fevrier 1996
- [ http://www.brouty.fr/Maths/pi.html ] */
- #ifdef S64BITS /* MACHINE CALCULANT SUR 64 BITS */
- #define TypInt long
- #define NBOCT 8 /* NOMBRE D'OCTETS SUR 64 BITS */
- #define BASE1 1000000000000000L /* BASE DE CALCUL: 10^15 */
- #define BASE2 100000000000000L /* BASE DE CALCUL: 10^14 */
- #define BASE3 10000000000000L /* BASE DE CALCUL: 10^13 */
- #define NBZ1 15 /* NOMBRE DE ZEROS DE BASE1 */
- #define NBZ2 14 /* NOMBRE DE ZEROS DE BASE2 */
- #define NBZ3 13 /* NOMBRE DE ZEROS DE BASE3 */
- #define NBIT2 13 /* 2^13 MULTPLICATEUR MINI POUR PASSER EN BASE 2*/
- #define GBASE1 4/* NOMBRE DE BLOCKS DE NBZ1 CHIFFRES AFFICHES PAR LIGNE*/
- #define GBASE2 4/* NOMBRE DE BLOCKS DE NBZ2 CHIFFRES AFFICHES PAR LIGNE*/
- #define GBASE3 5/* NOMBRE DE BLOCKS DE NBZ3 CHIFFRES AFFICHES PAR LIGNE*/
- #define LIMP1 6450 /* NOMBRE MAX DE DECIMALES CALCULEES POUR BASE1 */
- #define LIMP2 64471 /* NOMBRE MAX DE DECIMALES CALCULEES POUR BASE2 */
- #define LIMP3 644691 /* NOMBRE MAX DE DECIMALES CALCULEES POUR BASE3 */
- #endif
- #ifdef S32BITS /* MACHINE CALCULANT SUR 32 BITS */
- #define TypInt long
- #define NBOCT 4 /* NOMBRE D'OCTETS SUR 32 BITS */
- #define BASE1 1000000L
- #define BASE2 100000L
- #define BASE3 10000L
- #define NBZ1 6
- #define NBZ2 5
- #define NBZ3 4
- #define NBIT2 11 /* 2^11 MULTPLICATEUR MINI POUR PASSER EN BASE 2*/
- #define GBASE1 10/* NOMBRE DE BLOCKS DE NBZ1 CHIFFRES AFFICHES PAR LIGNE*/
- #define GBASE2 12/* NOMBRE DE BLOCKS DE NBZ2 CHIFFRES AFFICHES PAR LIGNE*/
- #define GBASE3 14/* NOMBRE DE BLOCKS DE NBZ3 CHIFFRES AFFICHES PAR LIGNE*/
- #define LIMP1 1501 /* NOMBRE MAX DE DECIMALES CALCULEES POUR BASE1 */
- #define LIMP2 15001 /* NOMBRE MAX DE DECIMALES CALCULEES POUR BASE2 */
- #define LIMP3 150001 /* NOMBRE MAX DE DECIMALES CALCULEES POUR BASE3 */
- #endif
- /* ON PEUT FORCER LE CALCUL SUR 32 BITS SUR UNE MACHINE A MOTS DE 64 BITS */
- /* AVEC L'OTION DE COMPILATION SUIVANTE. CELA PERMET DE COMPARER LE GAIN */
- /* DE PERFORMANCE QUAND ON UTILISE REELLEMENT LES 64 BITS DE LA MACHINE. */
- /* cc -DS32BITSFORCE -o pim2 pim2.c */
- #ifdef S32BITSFORCE
- #define TypInt int
- #define NBOCT 4 /* NOMBRE D'OCTETS SUR 32 BITS */
- #define BASE1 1000000
- #define BASE2 100000
- #define BASE3 10000
- #define NBZ1 6
- #define NBZ2 5
- #define NBZ3 4
- #define NBIT2 11 /* 2^11 MULTPLICATEUR MINI POUR PASSER EN BASE 2*/
- #define GBASE1 10/* NOMBRE DE BLOCKS DE NBZ1 CHIFFRES AFFICHES PAR LIGNE*/
- #define GBASE2 12/* NOMBRE DE BLOCKS DE NBZ2 CHIFFRES AFFICHES PAR LIGNE*/
- #define GBASE3 14/* NOMBRE DE BLOCKS DE NBZ3 CHIFFRES AFFICHES PAR LIGNE*/
- #define LIMP1 1501 /* NOMBRE MAX DE DECIMALES CALCULEES POUR BASE1 */
- #define LIMP2 15001 /* NOMBRE MAX DE DECIMALES CALCULEES POUR BASE2 */
- #define LIMP3 150001 /* NOMBRE MAX DE DECIMALES CALCULEES POUR BASE3 */
- #endif
- #define LOGb10_2 0.30103/* LOG BASE 10 DE 2 POUR CONVERSION EN BINAIRE */
- TypInt *resul; /* TROIS TABLEAUX DYNAMIQUES CONTENANT RESPECTIVEMENT */
- TypInt *resul1; /* LE RESULTAT FINAL ET LES RESULTATS INTERMEDIAIRES */
- TypInt *resul2;
- int K; /* GESTION DES CASES NULLES: INDICE DE LA 1ERE CASE NON NULLE */
- int MAX, MAXB; /* DIMENSION DES TABLEAUX */
- TypInt BASE; /* BASE DE NUMERATION CORRESPOND AU GROUPEMENT DES CHIFFRES */
- int GBASE; /* NOMBRE DE GROUPEMENT DES CHIFFRES POUR LA SORTIE */
- int I, J; /* NOMBRE D'ITERATIONS POUR CHAQUE ARCTG */
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int k, i, B2;
- int lim, limb; /* NOMBRE DE DECIMALES DEMANDEES */
- int NB;
- int Dec; /* 2^Dec = 1 << Dec */
- char *nam;
- nam = argv[0];
- B2 = 0;
- --argc; ++argv;
- lim = 0;
- while(argc) {
- if(*argv[0] == '-') {
- switch(*(argv[0] + 1)) {
- case '2':
- B2 = 1;
- break;
- default:
- Us(nam);
- break;
- }
- }
- else
- lim=atoi(argv[0]);
- --argc; ++argv;
- }
- if(lim == 0) {
- printf("Nombre de decimales souhaitees ( <= %d): ",LIMP3-1);
- scanf("%d",&lim);
- }
- if(B2) {
- limb = lim;
- lim = (int)((double)lim * LOGb10_2);
- }
- if(lim < LIMP1) {
- BASE=BASE1;
- NB=NBZ1;
- GBASE = B2 ? 1 + GBASE1/2 : GBASE1;
- Dec = NBIT2;
- }
- else {
- if(lim > LIMP3 - 1) {
- printf("Pas plus de %d decimales merci.\n",LIMP3-1);
- exit(0);
- }
- if(lim < LIMP2) {
- BASE=BASE2;
- NB=NBZ2;
- GBASE = B2 ? GBASE1/2 - 1 : GBASE2;
- Dec = NBIT2 + 3;
- }
- else {
- BASE=BASE3;
- NB=NBZ3;
- GBASE = B2 ? GBASE1/2 - 1 : GBASE3;
- Dec = NBIT2 + 6;
- }
- }
- if(B2)
- MAXB = 5+limb/Dec;
- MAX = 5+B2+lim/NB;
- resul=(TypInt *)malloc(NBOCT*MAX);
- resul1=(TypInt *)malloc(NBOCT*MAX);
- resul2=(TypInt *)malloc(NBOCT*MAX);
- memset((char *)resul1,0, NBOCT*MAX);
- memset((char *)resul2,0, NBOCT*MAX);
- memset((char *)resul,0, NBOCT*MAX);
- I=arctg_5(resul1,5,16);
- memcpy((char *)resul2,(char *)resul, NBOCT*MAX);
- memset((char *)resul,0, NBOCT*MAX);
- #ifdef S64BITS
- if(lim < LIMP1)
- J=arctg_239(resul1,239,4);
- else
- J=arctg_5(resul1,239,4); /* ON OPTIMISE:239^2 CA PASSE */
- #else
- if(lim < LIMP2)
- J=arctg_239(resul1,239,4);
- else
- J=arctg_5(resul1,239,4); /* ON OPTIMISE:239^2 CA PASSE */
- #endif
- K=2;
- sous(resul2,resul);
- if(B2) {
- printf("\n Decimales affichees: %d nombre d'iterations: %d , %d (%d)\n\n",Dec*(MAXB-4),I,J,I+J);
- tobin(resul2,Dec);
- }
- else {
- printf("\n Decimales affichees: %d nombre d'iterations: %d , %d (%d)\n\n",NB*(MAX-4),I,J,I+J);
- todec(resul2);
- }
- }
- todec(tab) /* CONVERSION EN DECIMAL */
- TypInt tab[];
- {
- register i;
- TypInt a;
- TypInt BS10 = BASE/10;
- printf("pi = %d,",tab[2]);
- for(i=3;i<MAX-1;++i) {
- a=tab[i];
- a = a == 0 ? 1L : a;
- while(a < BS10) {
- putchar('0');
- a=10*a;
- }
- printf("%lu%s",tab[i],(i-2)%GBASE ? " " : "\n ");
- }
- putchar('\n');
- }
- tobin(tab,nb) /* CONVERSION EN BINAIRE */
- TypInt tab[];
- int nb;
- {
- register i;
- TypInt a;
- char *bas2();
- a = (TypInt)(1 << (nb - 1));
- printf("pi= 11,");
- for(i=3;i<MAXB-1;++i) {
- tab[0] = 0;
- tab[1] = 0;
- tab[2] = 0;
- mul2(tab,nb);
- if(tab[1])
- tab[2] = BASE*BASE*tab[0] + BASE*tab[1] + tab[2];
- printf("%s%s",bas2(tab[2],a,nb),(i-2)%GBASE ? " " : "\n ");
- }
- putchar('\n');
- }
- char *bas2(b,p,n)/* AFFICHE LES CHIFFRES BINAIRES DE b PAR BLOC DE n CHIFFRES */
- TypInt b, p;
- int n;
- {
- short i;
- static char Base[256];
- memset(Base,0,256);
- for(i = 0; i < n ; ++i) {
- Base[i] = (b & (p >> i)) > 0 ? '1' : '0';
- }
- return(Base);
- }
- add(a,b) /* ADDITION DE DEUX TABLEAUX DE NOMBRES */
- TypInt a[], b[];
- {
- register i;
- TypInt register r=0; /* r EST LA RETENUE */
- for(i=MAX-1;i >= K;--i) {
- r=a[i]+r+b[i];
- if(r >= BASE) {
- a[i]=r-BASE;
- r=1;
- }
- else {
- a[i]=r;
- r=0;
- }
- }
- while(r) { /* PROPAGATION DE LA RETENUE */
- r=a[i]+r;
- if(r >= BASE) {
- a[i]=r-BASE;
- r=1;
- }
- else {
- a[i]=r;
- r=0;
- }
- --i;
- }
- }
- sous(a,b) /* SOUSTRACTION DE DEUX TABLEAUX DE NOMBRES. LE SIGNE DU */
- TypInt a[], b[]; /* RESULTAT EST SUPPOSE POSITIF */
- {
- register i;
- TypInt register r=0;
- for(i=MAX-1;i >= K;--i) {
- r=a[i]-r-b[i];
- if(r < 0) {
- a[i]=r+BASE;
- r=1;
- }
- else {
- a[i]=r;
- r=0;
- }
- }
- while(r) { /* PROPAGATION DE LA RETENUE */
- r=a[i]-r;
- if(r < 0) {
- a[i]=r+BASE;
- r=1;
- }
- else {
- a[i]=r;
- r=0;
- }
- --i;
- }
- }
- mul(tab,n) /* MULTIPLICATION D'UN TABLEAU DE NOMBRES PAR UN ENTIER POSITIF*/
- TypInt tab[], n;
- {
- register i;
- TypInt register S=0;
- for(i=MAX-1;i>=K;--i) {
- tab[i]=tab[i]*n+S;
- S=tab[i]/BASE;
- tab[i] = tab[i]%BASE;
- }
- tab[i]=tab[i]*n+S;
- while((S=tab[i])>=BASE) {
- tab[i-1] = tab[i-1] + S/BASE;
- tab[i] = S%BASE;
- --i; --K;
- }
- --K;
- while(tab[K] == 0) ++K;
- }
- mul2(tab,n) /* MULTIPLICATION D'UN TABLEAU DE NOMBRES PAR 2^n */
- TypInt tab[], n;
- {
- register i;
- TypInt register S=0;
- for(i=MAX-1;i>=K;--i) {
- tab[i] = (tab[i] << n) + S;
- S=tab[i]/BASE;
- tab[i] = tab[i]%BASE;
- }
- tab[i] = (tab[i] << n) + S;
- while((S=tab[i])>=BASE) {
- tab[i-1] = tab[i-1] + S/BASE;
- tab[i] = S%BASE;
- --i; --K;
- }
- --K;
- while(tab[K] == 0) ++K;
- }
- divisi(t,n) /* DIVISION D'UN TABLEAU DE NOMBRES PAR UN ENTIER */
- TypInt t[], n;
- {
- register i;
- TypInt register a;
- a=t[K];
- for(i=K;i<MAX;++i) {
- t[i]=a/n;
- a=BASE*(a%n)+t[i+1];
- }
- while(t[K] == 0) ++K; /* GESTION DES CASES NULLES */
- }
- arctg_239(tab,p,b) /* b*arctg(1/p) POUR p DE L'ORDRE DE GRANDEUR DE 239 */
- TypInt tab[], p, b;
- {
- register i;
- K=2;
- tab[2]=b;
- divisi(tab,p);
- add(resul,tab);
- for(i=0;K < MAX;++i) {
- divisi(tab,(2*i+3));
- divisi(tab,p);/*ON FAIT 2 DIVISIONS SUCCESSIVES AU LIEU D'UNE*/
- divisi(tab,p);/*POUR EVITER DE DEPASSER LES 31 (OU 63) BITS */
- mul(tab,(2*i + 1));
- (i+1)%2 ? sous(resul,tab) : add(resul,tab);
- }
- return(i);
- }
- arctg_5(tab,p,b) /* b*arctg(1/p) POUR p DE L'ORDRE DE GRANDEUR DE 5 */
- TypInt tab[], p, b;
- {
- register i;
- K=2;
- tab[2]=b;
- divisi(tab,p);
- add(resul,tab);
- p=p*p;
- for(i=0;K < MAX;++i) {
- divisi(tab,(2*i+3));
- divisi(tab,p);/*ICI p EST TROP PETIT POUR RISQUER DE DEPASSER */
- mul(tab,(2*i + 1)); /* LES 31 (OU 63) BITS. */
- (i+1)%2 ? sous(resul,tab) : add(resul,tab);
- }
- return(i);
- }
- Us(nom) /* USAGE DE LA COMMANDE */
- char *nom;
- {
- printf("Usage: %s [-2] [entier]\n\n\t-2: sortie en base 2\n\tentier: nombre de decimales desirees.\n",nom);
- exit(1);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement