source: git/Singular/modulop.cc @ 4c001a

spielwiese
Last change on this file since 4c001a was 4c001a, checked in by Olaf Bachmann <obachman@…>, 27 years ago
Merged fixes from 1-0-0 release git-svn-id: file:///usr/local/Singular/svn/trunk@358 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.7 1997-06-04 19:45:22 obachman 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    npExpTable=NULL;
223    npLogTable=NULL;
224  }
225  if ((c>1) || (c<(-1)))
226  {
227    if (c>1) npPrimeM = c;
228    else     npPrimeM = -c;
229    npPminus1M = npPrimeM - 1;
230    npExpTable= (CARDINAL *)Alloc( npPrimeM*sizeof(CARDINAL) );
231    npLogTable= (CARDINAL *)Alloc( npPrimeM*sizeof(CARDINAL) );
232    npExpTable[0] = 1;
233    npLogTable[1] = 0;
234    if (npPrimeM > 2)
235    {
236      w = 1;
237      loop
238      {
239        npLogTable[1] = 0;
240        w++;
241        i = 0;
242        loop
243        {
244          i++;
245          npExpTable[i] = (int)(((long)w * (long)npExpTable[i-1]) % npPrimeM);
246          npLogTable[npExpTable[i]] = i;
247          if (/*(i == npPrimeM - 1 ) ||*/ (npExpTable[i] == 1))
248            break;
249        }
250        if (i == npPrimeM - 1)
251          break;
252      }
253    }
254    else
255    {
256      npExpTable[1] = 1;
257    }
258  }
259  else
260    npPrimeM=0;
261 npGen=w;
262}
263
264
265#ifdef LDEBUG
266BOOLEAN npDBTest (number a, char *f, int l)
267{
268  if (((int)a<0) || ((int)a>npPrimeM))
269  {
270    return FALSE;
271  }
272  return TRUE;
273}
274#endif
275
276number npMap0(number from)
277{
278  return npInit(nlModP(from,npPrimeM));
279}
280
281number npMapP(number from)
282{
283  int i = (int)from;
284  if (i>npMapPrime/2)
285  {
286    i-=npMapPrime;
287    while (i < 0) i+=npPrimeM;
288  }
289  i%=npPrimeM;
290  return (number)i;
291}
292
293BOOLEAN npSetMap(int c, char ** par, int nop, number minpol)
294{
295  if (c == 0)
296  {
297    nMap = npMap0;   /*Q -> Z/p*/
298    return TRUE;
299  }
300  if (c == npPrimeM)
301  {
302    nMap = npCopy;  /* Z/p -> Z/p*/
303    return TRUE;
304  }
305  if (c>1)
306  {
307    if (par==NULL)
308    {
309      npMapPrime=c;
310      nMap = npMapP; /* Z/p' -> Z/p */
311      return TRUE;
312    }
313    else
314    {
315      return FALSE;   /* GF(q) ->Z/p */
316    }
317  }
318  if (c<0)
319  {
320    return FALSE;   /* Z/p'(a) -> Z/p*/
321  }
322  if (c==1)
323  {
324    return FALSE;   /* Q(a) -> Z/p */
325  }
326  return FALSE;      /* default */
327}
328
329/*2
330* dummy modulus: return 0
331*/
332number npIntMod(number a, number b)
333{
334  return (number)0;
335}
Note: See TracBrowser for help on using the repository browser.