/*************************************************************************************************************************************/
/*                                                                                                                                   */
/*        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 : %d puissance %d modulo %d = %d",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,"%08x",DECIMALES(valeur));                                                                           \
                    printf("\n%s = %.4s",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;

     for       (rang=rangD ; rang<=rangA ; rang++)
               {
               printf("\n position=%d",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");
               }
     }



Copyright © Jean-François Colonna, 2021-2023.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2021-2023.