PIPS
modulo.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include "linear_assert.h"
#include "arithmetique.h"
+ Include dependency graph for modulo.c:

Go to the source code of this file.

Macros

#define MODULO_MAX_A   5
 
#define MODULO_MAX_B   5
 

Functions

Value modulo_fast (Value a, Value b)
 package arithmetique More...
 

Macro Definition Documentation

◆ MODULO_MAX_A

#define MODULO_MAX_A   5

◆ MODULO_MAX_B

#define MODULO_MAX_B   5

Function Documentation

◆ modulo_fast()

Value modulo_fast ( Value  a,
Value  b 
)

package arithmetique

modulo.c

INTLIBRARY int modulo_fast(int a, int b): calcul du modulo de a par b; le modulo retourne est toujours positif

Il y a quatre configuration de signe a traiter:

  1. a>0 && b>0: a % b
  2. a<0 && b>0: a % b == 0 ? 0 : b - (-a)b
  3. a>0 && b<0: cf. 1. apres changement de signe de b
  4. a<0 && b<0: cf. 2. apres changement de signe de b

definition d'une look-up table pour les valeurs de a appartenant a [-MODULO_MAX_A..MODULO_MAX_A] et pour les valeurs de b appartenant a 1..MODULO_MAX_B Serait-il utile d'ajouter une test b==1 pour supprimer une colonne?

b == 1 2 3 4 5

a == - 5

a == - 4

a == - 3

a == - 2

a == - 1

a == 0

a == 1

a == 2

a == 3

a == 4

a == 5

supprime pour cause de look-up table if(a==1 || a== 0) return(a);

if(b==1) return(0);

Definition at line 48 of file modulo.c.

49 {
50  /* definition d'une look-up table pour les valeurs de a appartenant
51  a [-MODULO_MAX_A..MODULO_MAX_A] et pour les valeurs de b
52  appartenant a [1..MODULO_MAX_B] (en fait [-MODULO_MAX_B..MODULO_MAX_B]
53  a cause du changement de signe)
54  Serait-il utile d'ajouter une test b==1 pour supprimer une colonne?
55  */
56 #define MODULO_MAX_A 5
57 #define MODULO_MAX_B 5
58 
59  // should be generated automatically
60  static Value
61  modulo_look_up[2*MODULO_MAX_A+1][MODULO_MAX_B]= {
62  /* b == 1 2 3 4 5 */
63  {/* a == - 5 */ 0, 1, 1, 3, 0},
64  {/* a == - 4 */ 0, 0, 2, 0, 1},
65  {/* a == - 3 */ 0, 1, 0, 1, 2},
66  {/* a == - 2 */ 0, 0, 1, 2, 3},
67  {/* a == - 1 */ 0, 1, 2, 3, 4},
68  {/* a == 0 */ 0, 0, 0, 0, 0},
69  {/* a == 1 */ 0, 1, 1, 1, 1},
70  {/* a == 2 */ 0, 0, 2, 2, 2},
71  {/* a == 3 */ 0, 1, 0, 3, 3},
72  {/* a == 4 */ 0, 0, 1, 0, 4},
73  {/* a == 5 */ 0, 1, 2, 1, 0}
74  };
75 
76  // translation de a pour acces a la look-up table
77 
78  Value mod; // valeur du modulo C
80 
81  // premier changement de signe, ne changeant pas le resultat
82  b = value_abs(b);
83 
84  // traitement des cas particuliers
85  /* supprime pour cause de look-up table
86  * if(a==1 || a== 0)
87  * return(a);
88  *
89  * if(b==1)
90  * return(0);
91  */
92 
96  {
97  // acceleration par une look-up table
98  mod = modulo_look_up[VALUE_TO_INT(a)+MODULO_MAX_A][VALUE_TO_INT(b)-1];
99  }
100  else
101  {
102  // calcul effectif du modulo: attention, portabilite douteuse
103  mod = value_mod(a,b);
104  mod = value_neg_p(mod)? value_minus(b,mod): mod;
105  }
106 
107  return mod;
108 }
#define int_to_value(i)
end LINEAR_VALUE_IS_INT
#define value_minus(v1, v2)
#define VALUE_TO_INT(val)
#define value_le(v1, v2)
#define value_notzero_p(val)
int Value
#define value_abs(val)
#define value_mod(v1, v2)
#define value_ge(v1, v2)
#define value_neg_p(val)
#define MODULO_MAX_A
#define MODULO_MAX_B
#define assert(ex)
Definition: newgen_assert.h:41

References assert, int_to_value, MODULO_MAX_A, MODULO_MAX_B, value_abs, value_ge, value_le, value_minus, value_mod, value_neg_p, value_notzero_p, and VALUE_TO_INT.