source: git/Singular/modulop.cc @ 82716e

spielwiese
Last change on this file since 82716e was 511e7be, checked in by Hans Schönemann <hannes@…>, 27 years ago
* hannes: fixed bug with npGen (undefined in char 2) little optimisation in npSetChar git-svn-id: file:///usr/local/Singular/svn/trunk@786 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 5.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: modulop.cc,v 1.8 1997-10-09 09:36:23 Singular Exp $ */
5/*
6* ABSTRACT: numbers modulo p (<=32003)
7*/
8
9#include <limits.h>
10#include <string.h>
11#include "mod2.h"
12#include "tok.h"
13#include "febase.h"
14#include "mmemory.h"
15#include "numbers.h"
16#include "longrat.h"
17#include "modulop.h"
18
19int npPrimeM=0;
20int npGen=0;
21int npPminus1M=0;
22int npMapPrime;
23
24CARDINAL *npExpTable=NULL;
25CARDINAL *npLogTable=NULL;
26
27BOOLEAN npGreaterZero (number k)
28{
29  int h = (int) k;
30  return ((int)h !=0) && (h <= (npPrimeM>>1));
31}
32
33number npMult (number a,number b)
34{
35  if (((int)a == 0) || ((int)b == 0))
36    return (number)0;
37  else
38  {
39    return npMultM(a,b);
40  }
41}
42
43/*2
44* create a number from int
45*/
46number npInit (int i)
47{
48  while (i <  0)        i += npPrimeM;
49  while (i >= npPrimeM) i -= npPrimeM;
50  return (number)i;
51}
52
53/*2
54* convert a number to int (-p/2 .. p/2)
55*/
56int npInt(number &n)
57{
58  if ((int)n > (npPrimeM >>1)) return ((int)n -npPrimeM);
59  else                     return (int)n;
60}
61
62number npCopy (number  k1)
63{
64  return k1;
65}
66
67number npAdd (number a, number b)
68{
69  int ka = (int)a + (int)b;
70  if (ka >= npPrimeM) ka -= npPrimeM;
71  return (number)ka;
72}
73
74number npSub (number a, number b)
75{
76//  int ka = (int)a - (int)b;
77//  if (ka < 0)  ka += npPrimeM;
78//  *(int *)c = ka;
79  return npSubM(a,b);
80}
81
82BOOLEAN npIsZero (number  a)
83{
84  return 0 == (int)a;
85}
86
87BOOLEAN npIsOne (number a)
88{
89  return 1 == (int)a;
90}
91
92BOOLEAN npIsMOne (number a)
93{
94  return ((npPminus1M == (int)a)&&(1!=(int)a));
95}
96
97number npDiv (number a,number b)
98{
99  if ((int)a==0)
100    return (number)0;
101  else if ((int)b==0)
102  {
103    WerrorS("div by 0");
104    return (number)0;
105  }
106  else
107  {
108    int s = npLogTable[(int)a] - npLogTable[(int)b];
109    if (s < 0)
110      s += npPminus1M;
111    return (number)npExpTable[s];
112  }
113}
114
115number  npInvers (number c)
116{
117  if ((int)c==0)
118  {
119    WerrorS("1/0");
120    return (number)0;
121  }
122  return (number)npExpTable[npPminus1M - npLogTable[(int)c]];
123}
124
125number npNeg (number c)
126{
127//  *(int *)c = npPrimeM-*(int *)c;
128  return npNegM(c);
129}
130
131BOOLEAN npGreater (number a,number b)
132{
133  return (int)a != (int)b;
134}
135
136BOOLEAN npEqual (number a,number b)
137{
138//  return (int)a == (int)b;
139  return npEqualM(a,b);
140}
141
142void npWrite (number &a)
143{
144  if ((int)a > (npPrimeM >>1)) StringAppend("-%d",npPrimeM-((int)a));
145  else                     StringAppend("%d",(int)a);
146}
147
148void npPower (number a, int i, number * result)
149{
150  if (i==0)
151  {
152    //npInit(1,result);
153    *(int *)result = 1;
154  }
155  else if (i==1)
156  {
157    //*result = npCopy(a);
158    *result = a;
159  }
160  else
161  {
162    npPower(a,i-1,result);
163    *result = npMultM(a,*result);
164  }
165}
166
167char* npEati(char *s, int *i)
168{
169
170  if (((*s) >= '0') && ((*s) <= '9'))
171  {
172    (*i) = 0;
173    do
174    {
175      (*i) *= 10;
176      (*i) += *s++ - '0';
177      if ((*i) >= (INT_MAX / 10)) (*i) = (*i) % npPrimeM;
178    }
179    while (((*s) >= '0') && ((*s) <= '9'));
180    if ((*i) >= npPrimeM) (*i) = (*i) % npPrimeM;
181  }
182  else (*i) = 1;
183  return s;
184}
185
186char * npRead (char *s, number *a)
187{
188  int z;
189  int n=1;
190
191  s = npEati(s, &z);
192  if ((*s) == '/')
193  {
194    s++;
195    s = npEati(s, &n);
196  }
197  *a = npDiv((number)z,(number)n);
198  return s;
199}
200
201/*2
202* the last used charcteristic
203*/
204//int npGetChar()
205//{
206//  return npPrimeM;
207//}
208
209/*2
210* set the charcteristic (allocate and init tables)
211*/
212
213void npSetChar(int c)
214{
215  int i, w;
216
217  if (c==npPrimeM) return;
218  if (npPrimeM > 1)
219  {
220    Free( (ADDRESS)npExpTable,npPrimeM*sizeof(CARDINAL) );
221    Free( (ADDRESS)npLogTable,npPrimeM*sizeof(CARDINAL) );
222  }
223  if ((c>1) || (c<(-1)))
224  {
225    if (c>1) npPrimeM = c;
226    else     npPrimeM = -c;
227    npPminus1M = npPrimeM - 1;
228    npExpTable= (CARDINAL *)Alloc( npPrimeM*sizeof(CARDINAL) );
229    npLogTable= (CARDINAL *)Alloc( npPrimeM*sizeof(CARDINAL) );
230    npExpTable[0] = 1;
231    npLogTable[1] = 0;
232    if (npPrimeM > 2)
233    {
234      w = 1;
235      loop
236      {
237        npLogTable[1] = 0;
238        w++;
239        i = 0;
240        loop
241        {
242          i++;
243          npExpTable[i] = (int)(((long)w * (long)npExpTable[i-1]) % npPrimeM);
244          npLogTable[npExpTable[i]] = i;
245          if (/*(i == npPrimeM - 1 ) ||*/ (npExpTable[i] == 1))
246            break;
247        }
248        if (i == npPrimeM - 1)
249          break;
250      }
251      npGen=w;
252    }
253    else
254    {
255      npExpTable[1] = 1;
256      npGen=1;
257    }
258  }
259  else
260  {
261    npPrimeM=0;
262    npExpTable=NULL;
263    npLogTable=NULL;
264  }
265}
266
267
268#ifdef LDEBUG
269BOOLEAN npDBTest (number a, char *f, int l)
270{
271  if (((int)a<0) || ((int)a>npPrimeM))
272  {
273    return FALSE;
274  }
275  return TRUE;
276}
277#endif
278
279number npMap0(number from)
280{
281  return npInit(nlModP(from,npPrimeM));
282}
283
284number npMapP(number from)
285{
286  int i = (int)from;
287  if (i>npMapPrime/2)
288  {
289    i-=npMapPrime;
290    while (i < 0) i+=npPrimeM;
291  }
292  i%=npPrimeM;
293  return (number)i;
294}
295
296BOOLEAN npSetMap(int c, char ** par, int nop, number minpol)
297{
298  if (c == 0)
299  {
300    nMap = npMap0;   /*Q -> Z/p*/
301    return TRUE;
302  }
303  if (c == npPrimeM)
304  {
305    nMap = npCopy;  /* Z/p -> Z/p*/
306    return TRUE;
307  }
308  if (c>1)
309  {
310    if (par==NULL)
311    {
312      npMapPrime=c;
313      nMap = npMapP; /* Z/p' -> Z/p */
314      return TRUE;
315    }
316    else
317    {
318      return FALSE;   /* GF(q) ->Z/p */
319    }
320  }
321  if (c<0)
322  {
323    return FALSE;   /* Z/p'(a) -> Z/p*/
324  }
325  if (c==1)
326  {
327    return FALSE;   /* Q(a) -> Z/p */
328  }
329  return FALSE;      /* default */
330}
331
332/*2
333* dummy modulus: return 0
334*/
335number npIntMod(number a, number b)
336{
337  return (number)0;
338}
Note: See TracBrowser for help on using the repository browser.