/*************************************************************************************************************************************/
/* */
/* C A L C U L I N D I V I D U E L D E S C H I F F R E S D E P I E N B A S E 1 6 : */
/* */
/* */
/* ATTENTION : */
/* */
/* Cette methode est decrite a la */
/* page 54 du numero 1, volume 19 de */
/* The Mathematical Intelligencer. */
/* Ce programme est a compiler avec */
/* 'cc -64 -O3' sur 'SYSTEME_SGO200A1_IRIX_CC' */
/* par exemple. */
/* */
/* */
/* Author of '$xtc/pi_chif16.01$c' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, AAAAMMJJhhmmss). */
/* */
/*************************************************************************************************************************************/
#include <stdio.h>
extern double fmod();
extern double log();
extern double pow();
#define UN 1.0
#define DEUX 2.0
#define QUATRE 4.0
#define SEPT 7.0
#define HUIT 8.0
#define SEIZE 16
#define Entier long int
#define INTE(x) ((Entier)(x))
#define FLOT(x) ((double)(x))
#define MODU(x,m) ((x) % (m))
#define EXPONENTIELLE(exponentielle,base,exposant,modulo) \
{ \
Entier Cbase=base; \
Entier Cexposant=exposant; \
Entier Cmodulo=modulo; \
\
exponentielle=1; \
\
if (Cexposant > 0) \
{ \
Entier puissance_de_2; \
Entier iterer=0; \
\
puissance_de_2=INTE(pow(DEUX,FLOT(INTE(log(FLOT(Cexposant))/log(DEUX))))); \
\
while (iterer == 0) \
{ \
if (Cexposant >= puissance_de_2) \
{ \
exponentielle = MODU(Cbase*exponentielle,Cmodulo); \
Cexposant = Cexposant - puissance_de_2; \
} \
else \
{ \
} \
\
puissance_de_2 = puissance_de_2 / INTE(DEUX); \
\
if (puissance_de_2 >= 1) \
{ \
exponentielle = MODU(exponentielle*exponentielle,Cmodulo); \
} \
else \
{ \
iterer++; \
} \
} \
} \
else \
{ \
} \
\
if (exponentielle < 0) \
{ \
printf("\n exponentielle negative : %ld puissance %ld modulo %ld = %ld" \
,base \
,exposant \
,modulo \
,exponentielle \
); \
/* Ceci peut se produire lorsque les operations entieres donnent des resulats ne tenant */ \
/* pas dans 'Entier'... */ \
} \
else \
{ \
} \
} \
/* Calcul de : */ \
/* */ \
/* exposant */ \
/* exponentielle = base modulo */ \
/* */ \
/* quelle que soit (ou presque) la "taille"... */
#define CUMUL(serie,terme) \
serie = CORRIGE(serie + terme);
#define SERIE(serie,rang,increment) \
{ \
Entier base=SEIZE; \
Entier exposant; \
Entier modulo; \
Entier k; \
Entier precision=10; \
/* Parametre arbitraire permettant de prendre en compte quelques (=precision) termes */ \
/* de la serie apres le rang 'rang'... */ \
\
serie=0; \
\
for (k=0 ; k<=rang ; k++) \
{ \
Entier exponentielle; \
\
exposant = rang-k; \
\
modulo = (8*k)+(increment); \
EXPONENTIELLE(exponentielle,base,exposant,modulo); \
\
CUMUL(serie,FLOT(exponentielle)/FLOT(modulo)); \
} \
\
for (k=(rang+1) ; k<=(rang+precision) ; k++) \
{ \
exposant = rang-k; \
\
modulo = (8*k)+(increment); \
\
CUMUL(serie,pow(FLOT(base),FLOT(exposant))/FLOT(modulo)); \
} \
} \
/* Calcul de la serie : */ \
/* */ \
/* k=infini */ \
/* _____ */ \
/* \ 1 */ \
/* serie(increment) = / ---------------------- */ \
/* ----- k */ \
/* k=0 16 (8.k + increment) */ \
/* */
#define CORRIGE(x) \
fmod((x),UN)
#define DECIMALES(x) \
INTE(pow(FLOT(SEIZE),HUIT)*(x))
#define EDITE(valeur,titre) \
{ \
char chaine[]="12345678"; \
sprintf(chaine,"%lx",INTE(DECIMALES(valeur))); \
printf("%s = %.4s\n",titre,chaine); \
} \
/* Edition en hexa-decimal d'une valeur... */
main()
{
Entier rangD=999999;
Entier rangA=999999;
Entier rang;
Entier facteur1=+4,increment1=1;
Entier facteur2=-2,increment2=4;
Entier facteur3=-1,increment3=5;
Entier facteur4=-1,increment4=6;
double serie1;
double serie2;
double serie3;
double serie4;
double serie;
rangD=-1;
rangA=-1;
for (rang=rangD ; rang<=rangA ; rang++)
{
printf("position=%ld\n",rang+1);
SERIE(serie1,rang,increment1);
EDITE(serie1," serie 1");
SERIE(serie2,rang,increment2);
EDITE(serie2," serie 2");
SERIE(serie3,rang,increment3);
EDITE(serie3," serie 3");
SERIE(serie4,rang,increment4);
EDITE(serie4," serie 4");
serie = CORRIGE((facteur1*serie1) + (facteur2*serie2) + (facteur3*serie3) + (facteur4*serie4));
/* Calcul de pi : */
/* */
/* pi = 4.serie(1) - 2.serie(4) - 1.serie(5) - 1.serie(6) */
/* */
EDITE(serie," pi");
}
}