source: git/Singular/modulop.cc @ 416465

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