PIPS
modulo.c
Go to the documentation of this file.
1 /*
2 
3  $Id: modulo.c 1669 2019-06-26 17:24:57Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of Linear/C3 Library.
8 
9  Linear/C3 Library is free software: you can redistribute it and/or modify it
10  under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  Linear/C3 Library is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 /* package arithmetique
26  */
27 
28 /*LINTLIBRARY*/
29 
30 #ifdef HAVE_CONFIG_H
31  #include "config.h"
32 #endif
33 #include <stdlib.h>
34 #include <stdio.h>
35 
36 #include "linear_assert.h"
37 #include "arithmetique.h"
38 
39 /* int modulo_fast(int a, int b): calcul du modulo de a par b;
40  * le modulo retourne est toujours positif
41  *
42  * Il y a quatre configuration de signe a traiter:
43  * 1. a>0 && b>0: a % b
44  * 2. a<0 && b>0: a % b == 0 ? 0 : b - (-a)%b
45  * 3. a>0 && b<0: cf. 1. apres changement de signe de b
46  * 4. a<0 && b<0: cf. 2. apres changement de signe de b
47  */
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)
Value modulo_fast(Value a, Value b)
package arithmetique
Definition: modulo.c:48
#define MODULO_MAX_A
#define MODULO_MAX_B
#define assert(ex)
Definition: newgen_assert.h:41