source: git/kernel/rmodulo2m.cc @ 19370c

spielwiese
Last change on this file since 19370c was 4f8867, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: experimental:HAVE_RING2TOM git-svn-id: file:///usr/local/Singular/svn/trunk@9544 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: rmodulo2m.cc,v 1.6 2006-12-06 17:43:32 Singular Exp $ */
5/*
6* ABSTRACT: numbers modulo 2^m
7*/
8
9#include <string.h>
10#include "mod2.h"
11#include <mylimits.h>
12#include "structs.h"
13#include "febase.h"
14#include "omalloc.h"
15#include "numbers.h"
16#include "longrat.h"
17#include "mpr_complex.h"
18#include "ring.h"
19#include "rmodulo2m.h"
20
21#ifdef HAVE_RING2TOM
22int nr2mExp;
23long nr2mModul;
24
25/*
26 * Multiply two numbers
27 */
28number nr2mMult (number a,number b)
29{
30  if (((long)a == 0) || ((long)b == 0))
31    return (number)0;
32  else
33    return nr2mMultM(a,b);
34}
35
36/*
37 * Give the smallest non unit k, such that a * x = k = b * y has a solution
38 */
39number nr2mLcm (number a,number b,ring r)
40{
41  long res = 0;
42  if ((long) a == 0) a = (number) 1;
43  if ((long) b == 0) b = (number) 1;
44  while ((long) a % 2 == 0)
45  {
46    a = (number) ((long) a / 2);
47    if ((long) b % 2 == 0) b = (number) ((long) b / 2);
48    res++;
49  }
50  while ((long) b % 2 == 0)
51  {
52    b = (number) ((long) b / 2);
53    res++;
54  }
55  return (number) (1L << res);  // (2**res)
56}
57
58/*
59 * Give the largest non unit k, such that a = x * k, b = y * k has
60 * a solution.
61 */
62number nr2mGcd (number a,number b,ring r)
63{
64  long res = 0;
65  if ((long) a == 0 && (long) b == 0) return (number) 1;
66  while ((long) a % 2 == 0 && (long) b % 2 == 0)
67  {
68    a = (number) ((long) a / 2);
69    b = (number) ((long) b / 2);
70    res++;
71  }
72  if ((long) b % 2 == 0)
73  {
74    return (number) ((1L << res));// * (long) a);  // (2**res)*a    a ist Einheit
75  }
76  else
77  {
78    return (number) ((1L << res));// * (long) b);  // (2**res)*b    b ist Einheit
79  }
80}
81
82void nr2mPower (number a, int i, number * result)
83{
84  if (i==0)
85  {
86    //npInit(1,result);
87    *(long *)result = 1;
88  }
89  else if (i==1)
90  {
91    *result = a;
92  }
93  else
94  {
95    nr2mPower(a,i-1,result);
96    *result = nr2mMultM(a,*result);
97  }
98}
99
100/*
101 * create a number from int
102 */
103number nr2mInit (int i)
104{
105  long ii = i;
106  while (ii < 0) ii += nr2mModul;
107  while ((ii>1) && (ii >= nr2mModul)) ii -= nr2mModul;
108  return (number) ii;
109}
110
111/*
112 * convert a number to int (-p/2 .. p/2)
113 */
114int nr2mInt(number &n)
115{
116  if ((long)n > (nr2mModul >>1)) return (int)((long)n - nr2mModul);
117  else return (int)((long)n);
118}
119
120number nr2mAdd (number a, number b)
121{
122  return nr2mAddM(a,b);
123}
124
125number nr2mSub (number a, number b)
126{
127  return nr2mSubM(a,b);
128}
129
130BOOLEAN nr2mIsZero (number  a)
131{
132  return 0 == (long)a;
133}
134
135BOOLEAN nr2mIsOne (number a)
136{
137  return 1 == (long)a;
138}
139
140BOOLEAN nr2mIsMOne (number a)
141{
142  return nr2mModul == (long)a + 1;
143}
144
145BOOLEAN nr2mEqual (number a,number b)
146{
147  return nr2mEqualM(a,b);
148}
149
150BOOLEAN nr2mGreater (number a,number b)
151{
152  if ((long) a == 0) return TRUE;
153  if ((long) b == 0) return FALSE;
154  while ((long) a % 2 == 0 && (long) b % 2 == 0)
155  {
156    a = (number) ((long) a / 2);
157    b = (number) ((long) b / 2);
158}
159  return ((long) b % 2 == 1);
160}
161
162BOOLEAN nr2mGreaterZero (number k)
163{
164  int h = (int)((long) k);
165  return ((int)h !=0) && (h <= (nr2mModul>>1));
166}
167
168//#ifdef HAVE_DIV_MOD
169#if 1 //ifdef HAVE_NTL // in ntl.a
170//extern void XGCD(long& d, long& s, long& t, long a, long b);
171#include <NTL/ZZ.h>
172#ifdef NTL_CLIENT
173NTL_CLIENT
174#endif
175#else
176void XGCD(long& d, long& s, long& t, long a, long b)
177{
178   long  u, v, u0, v0, u1, v1, u2, v2, q, r;
179
180   long aneg = 0, bneg = 0;
181
182   if (a < 0) {
183      a = -a;
184      aneg = 1;
185   }
186
187   if (b < 0) {
188      b = -b;
189      bneg = 1;
190   }
191
192   u1=1; v1=0;
193   u2=0; v2=1;
194   u = a; v = b;
195
196   while (v != 0) {
197      q = u / v;
198      r = u % v;
199      u = v;
200      v = r;
201      u0 = u2;
202      v0 = v2;
203      u2 =  u1 - q*u2;
204      v2 = v1- q*v2;
205      u1 = u0;
206      v1 = v0;
207   }
208
209   if (aneg)
210      u1 = -u1;
211
212   if (bneg)
213      v1 = -v1;
214
215   d = u;
216   s = u1;
217   t = v1;
218}
219#endif
220
221long InvMod(long a)
222{
223   long d, s, t;
224
225   XGCD(d, s, t, a, nr2mModul);
226   assume (d == 1);
227   if (s < 0)
228      return s + nr2mModul;
229   else
230      return s;
231}
232//#endif
233
234inline number nr2mInversM (number c)
235{
236  // Table !!!
237  long inv;
238  inv = InvMod((long)c);
239  return (number) inv;
240}
241
242number nr2mDiv (number a,number b)
243{
244  if ((long)a==0)
245    return (number)0;
246  else if ((long)b%2==0)
247  {
248    if ((long)b != 0)
249    {
250      while ((long) b%2 == 0 && (long) a%2 == 0)
251      {
252        a = (number) ((long) a / 2);
253        b = (number) ((long) b / 2);
254      }
255    }
256    if ((long) b%2 == 0)
257    {
258      WerrorS("div by zero divisor");
259      return (number)0;
260    }
261  }
262  return (number) nr2mMult(a, nr2mInversM(b));
263}
264
265number nr2mIntDiv (number a,number b)
266{
267  if ((long)a==0)
268  {
269    return (number) 0;
270  }
271  else
272  {
273    return (number) ((long) a / (long) b);
274  }
275}
276
277number  nr2mInvers (number c)
278{
279  if ((long)c%2==0)
280  {
281    WerrorS("division by zero divisor");
282    return (number)0;
283  }
284  return nr2mInversM(c);
285}
286
287number nr2mNeg (number c)
288{
289  if ((long)c==0) return c;
290  return nr2mNegM(c);
291}
292
293nMapFunc nr2mSetMap(ring src, ring dst)
294{
295  return NULL;      /* default */
296}
297
298
299/*
300 * set the exponent (allocate and init tables) (TODO)
301 */
302
303void nr2mSetExp(int m, ring r)
304{
305  if (m>1)
306  {
307    nr2mExp = m;
308    nr2mModul = 2;
309    for (int i = 1; i < m; i++) {
310      nr2mModul = nr2mModul * 2;
311    }
312  }
313  else
314  {
315    nr2mExp=0;
316    nr2mModul=0;
317  }
318//  PrintS("Modul: ");
319//  Print("%d\n", nr2mModul);
320}
321
322void nr2mInitExp(int m, ring r)
323{
324  int i, w;
325
326  if (m>1)
327  {
328    nr2mExp = m;
329    nr2mModul = 2;
330    for (int i = 1; i < m; i++) {
331      nr2mModul = nr2mModul * 2;
332
333    }
334  }
335  else
336  {
337    WarnS("nInitChar failed");
338  }
339}
340
341#ifdef LDEBUG
342BOOLEAN nr2mDBTest (number a, char *f, int l)
343{
344  if (((long)a<0) || ((long)a>nr2mModul))
345  {
346    return FALSE;
347  }
348  return TRUE;
349}
350#endif
351
352void nr2mWrite (number &a)
353{
354  if ((long)a > (nr2mModul >>1)) StringAppend("-%d",(int)(nr2mModul-((long)a)));
355  else                          StringAppend("%d",(int)((long)a));
356}
357
358char* nr2mEati(char *s, int *i)
359{
360
361  if (((*s) >= '0') && ((*s) <= '9'))
362  {
363    (*i) = 0;
364    do
365    {
366      (*i) *= 10;
367      (*i) += *s++ - '0';
368      if ((*i) >= (MAX_INT_VAL / 10)) (*i) = (*i) % nr2mModul;
369    }
370    while (((*s) >= '0') && ((*s) <= '9'));
371    if ((*i) >= nr2mModul) (*i) = (*i) % nr2mModul;
372  }
373  else (*i) = 1;
374  return s;
375}
376
377char * nr2mRead (char *s, number *a)
378{
379  int z;
380  int n=1;
381
382  s = nr2mEati(s, &z);
383  if ((*s) == '/')
384  {
385    s++;
386    s = nr2mEati(s, &n);
387  }
388  if (n == 1)
389    *a = (number)z;
390  else
391      *a = nr2mDiv((number)z,(number)n);
392  return s;
393}
394#endif
Note: See TracBrowser for help on using the repository browser.