source: git/Singular/modulop.cc @ 9235af

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