source: git/kernel/longrat.cc @ b3af93

spielwiese
Last change on this file since b3af93 was e803ec, checked in by Hans Schönemann <hannes@…>, 15 years ago
*hannes: numerator, denominator git-svn-id: file:///usr/local/Singular/svn/trunk@12039 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 54.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: longrat.cc,v 1.43 2009-07-30 11:49:09 Singular Exp $ */
5/*
6* ABSTRACT: computation with long rational numbers (Hubert Grassmann)
7*/
8
9#ifndef LONGRAT_CC
10#define LONGRAT_CC
11
12#include <string.h>
13#include <float.h>
14#include "mod2.h"
15#include "structs.h"
16#include "omalloc.h"
17#include "febase.h"
18#include "numbers.h"
19#include "modulop.h"
20#include "ring.h"
21#include "shortfl.h"
22#include "mpr_complex.h"
23#include "longrat.h"
24
25
26#ifndef BYTES_PER_MP_LIMB
27#define BYTES_PER_MP_LIMB sizeof(mp_limb_t)
28#endif
29
30/*-----------------------------------------------------------------*/
31/*3
32* parameter s in number:
33* 0 (or FALSE): not normalised rational
34* 1 (or TRUE):  normalised rational
35* 3          :  integer with n==NULL
36*/
37/*3
38**  'SR_INT' is the type of those integers small enough to fit into  29  bits.
39**  Therefor the value range of this small integers is: $-2^{28}...2^{28}-1$.
40**
41**  Small integers are represented by an immediate integer handle, containing
42**  the value instead of pointing  to  it,  which  has  the  following  form:
43**
44**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
45**      | guard | sign  | bit   | bit   |       | bit   | tag   | tag   |
46**      | bit   | bit   | 27    | 26    |       | 0     | 0     | 1     |
47**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
48**
49**  Immediate integers handles carry the tag 'SR_INT', i.e. the last bit is 1.
50**  This distuingishes immediate integers from other handles which  point  to
51**  structures aligned on 4 byte boundaries and therefor have last bit  zero.
52**  (The second bit is reserved as tag to allow extensions of  this  scheme.)
53**  Using immediates as pointers and dereferencing them gives address errors.
54**
55**  To aid overflow check the most significant two bits must always be equal,
56**  that is to say that the sign bit of immediate integers has a  guard  bit.
57**
58**  The macros 'INT_TO_SR' and 'SR_TO_INT' should be used to convert  between
59**  a small integer value and its representation as immediate integer handle.
60**
61**  Large integers and rationals are represented by z and n
62**  where n may be undefined (if s==3)
63**  NULL represents only deleted values
64*/
65#define SR_HDL(A) ((long)(A))
66/*#define SR_INT    1L*/
67/*#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))*/
68// #define SR_TO_INT(SR)   (((long)SR) >> 2)
69
70#define MP_SMALL 1
71//#define mpz_isNeg(A) (mpz_cmp_si(A,(long)0)<0)
72#define mpz_isNeg(A) ((A)->_mp_size<0)
73#define mpz_limb_size(A) ((A)->_mp_size)
74#define mpz_limb_d(A) ((A)->_mp_d)
75#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
76#define MPZ_EXACTDIV(A,B,C) mpz_divexact((A),(B),(C))
77
78void    _nlDelete_NoImm(number *a);
79
80/***************************************************************
81 *
82 * Routines which are never inlined by p_Numbers.h
83 *
84 *******************************************************************/
85#ifndef P_NUMBERS_H
86
87omBin rnumber_bin = omGetSpecBin(sizeof(snumber));
88
89number nlOne=INT_TO_SR(1);
90
91#if (__GNU_MP_VERSION*10+__GNU_MP_VERSION_MINOR < 31)
92void mpz_mul_si (mpz_ptr r, mpz_srcptr s, long int si)
93{
94  if (si>=0)
95    mpz_mul_ui(r,s,si);
96  else
97  {
98    mpz_mul_ui(r,s,-si);
99    mpz_neg(r,r);
100  }
101}
102#endif
103
104static int nlPrimeM;
105static number nlMapP(number from)
106{
107  number to;
108  int save=npPrimeM;
109  npPrimeM=nlPrimeM;
110  to = nlInit(npInt(from));
111  npPrimeM=save;
112  return to;
113}
114
115static number nlMapLongR(number from);
116static number nlMapR(number from);
117
118#ifdef HAVE_RINGS
119/*2
120* convert from a GMP integer
121*/
122number nlMapGMP(number from)
123{
124  number z=(number)omAllocBin(rnumber_bin);
125#if defined(LDEBUG)
126  z->debug=123456;
127#endif
128  mpz_init_set(&z->z,(MP_INT*) from);
129  //mpz_init_set_ui(&z->n,1);
130  z->s = 3;
131  nlNormalize(z);
132  return z;
133}
134
135/*2
136* convert from an machine long
137*/
138number nlMapMachineInt(number from)
139{
140  number z=(number)omAllocBin(rnumber_bin);
141#if defined(LDEBUG)
142  z->debug=123456;
143#endif
144  mpz_init_set_ui(&z->z,(unsigned long) from);
145  //mpz_init_set_ui(&z->n,1);
146  z->s = 3;
147  nlNormalize(z);
148  return z;
149}
150#endif
151
152nMapFunc nlSetMap(ring src, ring dst)
153{
154  if (rField_is_Q(src))
155  {
156    return nlCopy;
157  }
158  if (rField_is_Zp(src))
159  {
160    nlPrimeM=rChar(src);
161    return nlMapP;
162  }
163  if (rField_is_R(src))
164  {
165    return nlMapR;
166  }
167  if (rField_is_long_R(src))
168  {
169    return nlMapLongR; /* long R -> Q */
170  }
171#ifdef HAVE_RINGS
172  if (rField_is_Ring_Z(src) || rField_is_Ring_PtoM(src) || rField_is_Ring_ModN(src))
173  {
174    return nlMapGMP;
175  }
176  if (rField_is_Ring_2toM(src))
177  {
178    return nlMapMachineInt;
179  }
180#endif
181  return NULL;
182}
183
184#ifdef LDEBUG
185BOOLEAN nlDBTest(number a, const char *f,const int l)
186{
187  if (a==NULL)
188  {
189    Print("!!longrat: NULL in %s:%d\n",f,l);
190    return FALSE;
191  }
192  //if ((int)a==1) Print("!! 0x1 as number ? %s %d\n",f,l);
193  if ((((long)a)&3L)==3L)
194  {
195    Print(" !!longrat:ptr(3) in %s:%d\n",f,l);
196    return FALSE;
197  }
198  if ((((long)a)&3L)==1L)
199  {
200    if (((((long)a)<<1)>>1)!=((long)a))
201    {
202      Print(" !!longrat:arith:%lx in %s:%d\n",(long)a, f,l);
203      return FALSE;
204    }
205    return TRUE;
206  }
207  omCheckIf(omCheckAddrSize(a,sizeof(*a)), return FALSE);
208  if (a->debug!=123456)
209  {
210    Print("!!longrat:debug:%d in %s:%d\n",a->debug,f,l);
211    a->debug=123456;
212    return FALSE;
213  }
214  if ((a->s<0)||(a->s>4))
215  {
216    Print("!!longrat:s=%d in %s:%d\n",a->s,f,l);
217    return FALSE;
218  }
219  omCheckAddrSize(a->z._mp_d,a->z._mp_alloc*BYTES_PER_MP_LIMB);
220  if (a->z._mp_alloc==0)
221    Print("!!longrat:z->alloc=0 in %s:%d\n",f,l);
222
223  if (a->s<2)
224  {
225    omCheckIf(omCheckAddrSize(a->n._mp_d,a->n._mp_alloc*BYTES_PER_MP_LIMB), return FALSE);
226    if (a->z._mp_alloc==0)
227      Print("!!longrat:n->alloc=0 in %s:%d\n",f,l);
228    if ((mpz_size1(&a->n) ==1) && (mpz_cmp_si(&a->n,(long)1)==0))
229    {
230      Print("!!longrat:integer as rational in %s:%d\n",f,l);
231      return FALSE;
232    }
233    else if (mpz_isNeg(&a->n))
234    {
235      Print("!!longrat:div. by negative in %s:%d\n",f,l);
236      mpz_neg(&a->z,&a->z);
237      mpz_neg(&a->n,&a->n);
238      return FALSE;
239    }
240    return TRUE;
241  }
242  if (a->s==2)
243  {
244    Print("!!longrat:s=2 in %s:%d\n",f,l);
245    return FALSE;
246  }
247  if (mpz_size1(&a->z)>MP_SMALL) return TRUE;
248  int ui=(int)mpz_get_si(&a->z);
249  if ((((ui<<3)>>3)==ui)
250  && (mpz_cmp_si(&a->z,(long)ui)==0))
251  {
252    Print("!!longrat:im int %d in %s:%d\n",ui,f,l);
253    f=NULL;
254    return FALSE;
255  }
256  return TRUE;
257}
258#endif
259
260number nlRInit (int i);
261
262static number nlMapR(number from)
263{
264  double f=nrFloat(from);
265  if (f==0.0) return INT_TO_SR(0);
266  int f_sign=1;
267  if (f<0.0)
268  {
269    f_sign=-1;
270    f=-f;
271  }
272  int i=0;
273  mpz_t h1;
274  mpz_init_set_ui(h1,1);
275  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
276  {
277    f*=FLT_RADIX;
278    mpz_mul_ui(h1,h1,FLT_RADIX);
279    i++;
280  }
281  number r=nlRInit(1);
282  mpz_set_d(&(r->z),f);
283  memcpy4(&(r->n),&h1,sizeof(h1));
284  r->s=0; /* not normalized */
285  nlNormalize(r);
286  return r;
287}
288
289static number nlMapLongR(number from)
290{
291  gmp_float *ff=(gmp_float*)from;
292  mpf_t *f=ff->_mpfp();
293  number res;
294  lint *dest,*ndest;
295  int size, i,negative;
296  int e,al,bl;
297  mp_ptr qp,dd,nn;
298
299  size = (*f)[0]._mp_size;
300  if (size == 0)
301    return INT_TO_SR(0);
302  if(size<0)
303  {
304    negative = 1;
305    size = -size;
306  }
307  else
308    negative = 0;
309
310  qp = (*f)[0]._mp_d;
311  while(qp[0]==0)
312  {
313    qp++;
314    size--;
315  }
316
317  e=(*f)[0]._mp_exp-size;
318  res = (number)omAllocBin(rnumber_bin);
319#if defined(LDEBUG)
320  res->debug=123456;
321#endif
322  dest = &(res->z);
323
324  if (e<0)
325  {
326    al = dest->_mp_size = size;
327    if (al<2) al = 2;
328    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
329    for (i=0;i<size;i++) dd[i] = qp[i];
330    bl = 1-e;
331    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
332    nn[bl-1] = 1;
333    for (i=bl-2;i>=0;i--) nn[i] = 0;
334    ndest = &(res->n);
335    ndest->_mp_d = nn;
336    ndest->_mp_alloc = ndest->_mp_size = bl;
337    res->s = 0;
338  }
339  else
340  {
341    al = dest->_mp_size = size+e;
342    if (al<2) al = 2;
343    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
344    for (i=0;i<size;i++) dd[i+e] = qp[i];
345    for (i=0;i<e;i++) dd[i] = 0;
346    res->s = 3;
347  }
348
349  dest->_mp_d = dd;
350  dest->_mp_alloc = al;
351  if (negative) dest->_mp_size = -dest->_mp_size;
352
353  if (res->s==0)
354    nlNormalize(res);
355  else if (mpz_size1(&res->z)<=MP_SMALL)
356  {
357    // res is new, res->ref is 1
358    int ui=(int)mpz_get_si(&res->z);
359    if ((((ui<<3)>>3)==ui)
360       && (mpz_cmp_si(&res->z,(long)ui)==0))
361    {
362       mpz_clear(&res->z);
363#if defined(LDEBUG)
364       res->debug=654324;
365#endif
366       omFreeBin((ADDRESS)res, rnumber_bin);
367       return INT_TO_SR(ui);
368    }
369  }
370#if defined(LDEBUG)
371  nlTest(res);
372#endif
373  return res;
374}
375
376//static number nlMapLongR(number from)
377//{
378//  gmp_float *ff=(gmp_float*)from;
379//  const mpf_t *f=ff->mpfp();
380//  int f_size=ABS((*f)[0]._mp_size);
381//  if (f_size==0)
382//    return nlInit(0);
383//  int f_sign=1;
384//  number work=ngcCopy(from);
385//  if (!ngcGreaterZero(work))
386//  {
387//    f_sign=-1;
388//    work=ngcNeg(work);
389//  }
390//  int i=0;
391//  mpz_t h1;
392//  mpz_init_set_ui(h1,1);
393//  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
394//  {
395//    f*=FLT_RADIX;
396//    mpz_mul_ui(h1,h1,FLT_RADIX);
397//    i++;
398//  }
399//  number r=nlRInit(1);
400//  mpz_set_d(&(r->z),f);
401//  memcpy4(&(r->n),&h1,sizeof(h1));
402//  r->s=0; /* not normalized */
403//  nlNormalize(r);
404//  return r;
405//
406//
407//  number r=nlRInit(1);
408//  int f_shift=f_size+(*f)[0]._mp_exp;
409//  if ( f_shift > 0)
410//  {
411//    r->s=0;
412//    mpz_init(&r->n);
413//    mpz_setbit(&r->n,f_shift*BYTES_PER_MP_LIMB*8);
414//    mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
415//    // now r->z has enough space
416//    memcpy4(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
417//    nlNormalize(r);
418//  }
419//  else
420//  {
421//    r->s=3;
422//    if (f_shift==0)
423//    {
424//      mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
425//      // now r->z has enough space
426//      memcpy4(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
427//    }
428//    else /* f_shift < 0 */
429//    {
430//      mpz_setbit(&r->z,(f_size-f_shift)*BYTES_PER_MP_LIMB*8-1);
431//      // now r->z has enough space
432//      memcpy4(mpz_limb_d(&r->z)-f_shift,((*f)[0]._mp_d),
433//        f_size*BYTES_PER_MP_LIMB);
434//    }
435//  }
436//  if ((*f)[0]._mp_size<0);
437//    r=nlNeg(r);
438//  return r;
439//}
440
441int nlSize(number a)
442{
443  if (a==INT_TO_SR(0))
444     return 0; /* rational 0*/
445  if (SR_HDL(a) & SR_INT)
446     return 1; /* immidiate int */
447  int s=a->z._mp_alloc;
448//  while ((s>0) &&(a->z._mp_d[s]==0L)) s--;
449//#if SIZEOF_LONG == 8
450//  if (a->z._mp_d[s] < (unsigned long)0x100000000L) s=s*2-1;
451//  else s *=2;
452//#endif
453//  s++;
454  if (a->s<2)
455  {
456    int d=a->n._mp_alloc;
457//    while ((d>0) && (a->n._mp_d[d]==0L)) d--;
458//#if SIZEOF_LONG == 8
459//    if (a->n._mp_d[d] < (unsigned long)0x100000000L) d=d*2-1;
460//    else d *=2;
461//#endif
462    s+=d;
463  }
464  return s;
465}
466
467/*2
468* convert number to int
469*/
470int nlInt(number &i)
471{
472#ifdef LDEBUG
473  nlTest(i);
474#endif
475  nlNormalize(i);
476  if (SR_HDL(i) &SR_INT) return SR_TO_INT(i);
477  if (i->s==3)
478  {
479    if(mpz_size1(&i->z)>MP_SMALL) return 0;
480    int ul=(int)mpz_get_si(&i->z);
481    if (mpz_cmp_si(&i->z,(long)ul)!=0) return 0;
482    return ul;
483  }
484  lint tmp;
485  int ul;
486  mpz_init(&tmp);
487  MPZ_DIV(&tmp,&i->z,&i->n);
488  if(mpz_size1(&tmp)>MP_SMALL) ul=0;
489  else
490  {
491    ul=(int)mpz_get_si(&tmp);
492    if (mpz_cmp_si(&tmp,(long)ul)!=0) ul=0;
493  }
494  mpz_clear(&tmp);
495  return ul;
496}
497
498/*2
499* convert number to bigint
500*/
501number nlBigInt(number &i)
502{
503#ifdef LDEBUG
504  nlTest(i);
505#endif
506  nlNormalize(i);
507  if (SR_HDL(i) &SR_INT) return (i);
508  if (i->s==3)
509  {
510    return nlCopy(i);
511  }
512  number tmp=nlRInit(1);
513  MPZ_DIV(&tmp->z,&i->z,&i->n);
514  nlNormalize(tmp);
515  return tmp;
516}
517
518/*
519* 1/a
520*/
521number nlInvers(number a)
522{
523#ifdef LDEBUG
524  nlTest(a);
525#endif
526  number n;
527  if (SR_HDL(a) & SR_INT)
528  {
529    if ((a==INT_TO_SR(1)) || (a==INT_TO_SR(-1)))
530    {
531      return a;
532    }
533    if (nlIsZero(a))
534    {
535      WerrorS(nDivBy0);
536      return INT_TO_SR(0);
537    }
538    n=(number)omAllocBin(rnumber_bin);
539#if defined(LDEBUG)
540    n->debug=123456;
541#endif
542    n->s=1;
543    if ((long)a>0L)
544    {
545      mpz_init_set_si(&n->z,(long)1);
546      mpz_init_set_si(&n->n,(long)SR_TO_INT(a));
547    }
548    else
549    {
550      mpz_init_set_si(&n->z,(long)-1);
551      mpz_init_set_si(&n->n,(long)-SR_TO_INT(a));
552    }
553#ifdef LDEBUG
554    nlTest(n);
555#endif
556    return n;
557  }
558  n=(number)omAllocBin(rnumber_bin);
559#if defined(LDEBUG)
560  n->debug=123456;
561#endif
562  {
563    n->s=a->s;
564    mpz_init_set(&n->n,&a->z);
565    switch (a->s)
566    {
567      case 0:
568      case 1:
569              mpz_init_set(&n->z,&a->n);
570              if (mpz_isNeg(&n->n)) /* && n->s<2*/
571              {
572                mpz_neg(&n->z,&n->z);
573                mpz_neg(&n->n,&n->n);
574              }
575              if (mpz_cmp_si(&n->n,(long)1)==0)
576              {
577                mpz_clear(&n->n);
578                n->s=3;
579                if (mpz_size1(&n->z)<=MP_SMALL)
580                {
581                  int ui=(int)mpz_get_si(&n->z);
582                  if ((((ui<<3)>>3)==ui)
583                  && (mpz_cmp_si(&n->z,(long)ui)==0))
584                  {
585                    mpz_clear(&n->z);
586#if defined(LDEBUG)
587                    n->debug=654324;
588#endif
589                    omFreeBin((ADDRESS)n, rnumber_bin);
590                    n=INT_TO_SR(ui);
591                  }
592                }
593              }
594              break;
595      case 3:
596              n->s=1;
597              if (mpz_isNeg(&n->n)) /* && n->s<2*/
598              {
599                mpz_neg(&n->n,&n->n);
600                mpz_init_set_si(&n->z,(long)-1);
601              }
602              else
603              {
604                mpz_init_set_si(&n->z,(long)1);
605              }
606              break;
607    }
608  }
609#ifdef LDEBUG
610  nlTest(n);
611#endif
612  return n;
613}
614
615
616/*2
617* u := a / b in Z, if b | a (else undefined)
618*/
619number   nlExactDiv(number a, number b)
620{
621  if (b==INT_TO_SR(0))
622  {
623    WerrorS(nDivBy0);
624    return INT_TO_SR(0);
625  }
626  if (a==INT_TO_SR(0))
627    return INT_TO_SR(0);
628  number u;
629  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
630  {
631    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
632    if ((a==INT_TO_SR(-(1<<28)))&&(b==INT_TO_SR(-1)))
633    {
634      return nlRInit(1<<28);
635    }
636    int aa=SR_TO_INT(a);
637    int bb=SR_TO_INT(b);
638    return INT_TO_SR(aa/bb);
639  }
640  number bb=NULL;
641  if (SR_HDL(b) & SR_INT)
642  {
643    bb=nlRInit(SR_TO_INT(b));
644    b=bb;
645  }
646  u=(number)omAllocBin(rnumber_bin);
647#if defined(LDEBUG)
648  u->debug=123456;
649#endif
650  mpz_init(&u->z);
651  /* u=a/b */
652  u->s = 3;
653  MPZ_EXACTDIV(&u->z,&a->z,&b->z);
654  if (bb!=NULL)
655  {
656    mpz_clear(&bb->z);
657#if defined(LDEBUG)
658    bb->debug=654324;
659#endif
660    omFreeBin((ADDRESS)bb, rnumber_bin);
661  }
662  if (mpz_size1(&u->z)<=MP_SMALL)
663  {
664    int ui=(int)mpz_get_si(&u->z);
665    if ((((ui<<3)>>3)==ui)
666    && (mpz_cmp_si(&u->z,(long)ui)==0))
667    {
668      mpz_clear(&u->z);
669#if defined(LDEBUG)
670      u->debug=654324;
671#endif
672      omFreeBin((ADDRESS)u, rnumber_bin);
673      u=INT_TO_SR(ui);
674    }
675  }
676#ifdef LDEBUG
677  nlTest(u);
678#endif
679  return u;
680}
681
682/*2
683* u := a / b in Z
684*/
685number nlIntDiv (number a, number b)
686{
687  if (b==INT_TO_SR(0))
688  {
689    WerrorS(nDivBy0);
690    return INT_TO_SR(0);
691  }
692  if (a==INT_TO_SR(0))
693    return INT_TO_SR(0);
694  number u;
695  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
696  {
697    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
698    if ((a==INT_TO_SR(-(1<<28)))&&(b==INT_TO_SR(-1)))
699    {
700      return nlRInit(1<<28);
701    }
702    int aa=SR_TO_INT(a);
703    int bb=SR_TO_INT(b);
704    return INT_TO_SR(aa/bb);
705  }
706  if (SR_HDL(a) & SR_INT)
707  {
708    /* the small int -(1<<28) divided by 2^28 is 1   */
709    if (a==INT_TO_SR(-(1<<28)))
710    {
711      if(mpz_cmp_si(&b->z,(long)(1<<28))==0)
712      {
713        return INT_TO_SR(-1);
714      }
715    }
716    /* a is a small and b is a large int: -> 0 */
717    return INT_TO_SR(0);
718  }
719  number bb=NULL;
720  if (SR_HDL(b) & SR_INT)
721  {
722    bb=nlRInit(SR_TO_INT(b));
723    b=bb;
724  }
725  u=(number)omAllocBin(rnumber_bin);
726#if defined(LDEBUG)
727  u->debug=123456;
728#endif
729  assume(a->s==3);
730  assume(b->s==3);
731  mpz_init_set(&u->z,&a->z);
732  /* u=u/b */
733  u->s = 3;
734  MPZ_DIV(&u->z,&u->z,&b->z);
735  if (bb!=NULL)
736  {
737    mpz_clear(&bb->z);
738#if defined(LDEBUG)
739    bb->debug=654324;
740#endif
741    omFreeBin((ADDRESS)bb, rnumber_bin);
742  }
743  if (mpz_size1(&u->z)<=MP_SMALL)
744  {
745    int ui=(int)mpz_get_si(&u->z);
746    if ((((ui<<3)>>3)==ui)
747    && (mpz_cmp_si(&u->z,(long)ui)==0))
748    {
749      mpz_clear(&u->z);
750#if defined(LDEBUG)
751      u->debug=654324;
752#endif
753      omFreeBin((ADDRESS)u, rnumber_bin);
754      u=INT_TO_SR(ui);
755    }
756  }
757#ifdef LDEBUG
758  nlTest(u);
759#endif
760  return u;
761}
762
763/*2
764* u := a mod b in Z, u>=0
765*/
766number nlIntMod (number a, number b)
767{
768  if (b==INT_TO_SR(0))
769  {
770    WerrorS(nDivBy0);
771    return INT_TO_SR(0);
772  }
773  if (a==INT_TO_SR(0))
774    return INT_TO_SR(0);
775  number u;
776  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
777  {
778    if ((long)a>0L)
779    {
780      if ((long)b>0L)
781        return INT_TO_SR(SR_TO_INT(a)%SR_TO_INT(b));
782      else
783        return INT_TO_SR(SR_TO_INT(a)%(-SR_TO_INT(b)));
784    }
785    else
786    {
787      if ((long)b>0L)
788      {
789        int i=(-SR_TO_INT(a))%SR_TO_INT(b);
790        if ( i != 0 ) i = (SR_TO_INT(b))-i;
791        return INT_TO_SR(i);
792      }
793      else
794      {
795        int i=(-SR_TO_INT(a))%(-SR_TO_INT(b));
796        if ( i != 0 ) i = (-SR_TO_INT(b))-i;
797        return INT_TO_SR(i);
798      }
799    }
800  }
801  if (SR_HDL(a) & SR_INT)
802  {
803    /* a is a small and b is a large int: -> a or (a+b) or (a-b) */
804    if ((long)a<0L)
805    {
806      if (mpz_isNeg(&b->z))
807        return nlSub(a,b);
808      /*else*/
809        return nlAdd(a,b);
810    }
811    /*else*/
812      return a;
813  }
814  number bb=NULL;
815  if (SR_HDL(b) & SR_INT)
816  {
817    bb=nlRInit(SR_TO_INT(b));
818    b=bb;
819  }
820  u=(number)omAllocBin(rnumber_bin);
821#if defined(LDEBUG)
822  u->debug=123456;
823#endif
824  mpz_init(&u->z);
825  u->s = 3;
826  mpz_mod(&u->z,&a->z,&b->z);
827  if (bb!=NULL)
828  {
829    mpz_clear(&bb->z);
830#if defined(LDEBUG)
831    bb->debug=654324;
832#endif
833    omFreeBin((ADDRESS)bb, rnumber_bin);
834  }
835  if (mpz_isNeg(&u->z))
836  {
837    if (mpz_isNeg(&b->z))
838      mpz_sub(&u->z,&u->z,&b->z);
839    else
840      mpz_add(&u->z,&u->z,&b->z);
841  }
842  if (mpz_size1(&u->z)<=MP_SMALL)
843  {
844    int ui=(int)mpz_get_si(&u->z);
845    if ((((ui<<3)>>3)==ui)
846    && (mpz_cmp_si(&u->z,(long)ui)==0))
847    {
848      mpz_clear(&u->z);
849#if defined(LDEBUG)
850      u->debug=654324;
851#endif
852      omFreeBin((ADDRESS)u, rnumber_bin);
853      u=INT_TO_SR(ui);
854    }
855  }
856#ifdef LDEBUG
857  nlTest(u);
858#endif
859  return u;
860}
861
862/*2
863* u := a / b
864*/
865number nlDiv (number a, number b)
866{
867  number u;
868  if (nlIsZero(b))
869  {
870    WerrorS(nDivBy0);
871    return INT_TO_SR(0);
872  }
873  u=(number)omAllocBin(rnumber_bin);
874  u->s=0;
875#if defined(LDEBUG)
876  u->debug=123456;
877#endif
878// ---------- short / short ------------------------------------
879  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
880  {
881    int i=SR_TO_INT(a);
882    int j=SR_TO_INT(b);
883    int r=i%j;
884    if (r==0)
885    {
886      omFreeBin((ADDRESS)u, rnumber_bin);
887      return INT_TO_SR(i/j);
888    }
889    mpz_init_set_si(&u->z,(long)i);
890    mpz_init_set_si(&u->n,(long)j);
891  }
892  else
893  {
894    mpz_init(&u->z);
895// ---------- short / long ------------------------------------
896    if (SR_HDL(a) & SR_INT)
897    {
898      // short a / (z/n) -> (a*n)/z
899      if (b->s<2)
900      {
901        mpz_mul_si(&u->z,&b->n,SR_TO_INT(a));
902      }
903      else
904      // short a / long z -> a/z
905      {
906        mpz_set_si(&u->z,SR_TO_INT(a));
907      }
908      if (mpz_cmp(&u->z,&b->z)==0)
909      {
910        mpz_clear(&u->z);
911        omFreeBin((ADDRESS)u, rnumber_bin);
912        return INT_TO_SR(1);
913      }
914      mpz_init_set(&u->n,&b->z);
915    }
916// ---------- long / short ------------------------------------
917    else if (SR_HDL(b) & SR_INT)
918    {
919      mpz_set(&u->z,&a->z);
920      // (z/n) / b -> z/(n*b)
921      if (a->s<2)
922      {
923        mpz_init_set(&u->n,&a->n);
924        if ((long)b>0L)
925          mpz_mul_ui(&u->n,&u->n,SR_TO_INT(b));
926        else
927        {
928          mpz_mul_ui(&u->n,&u->n,-SR_TO_INT(b));
929          mpz_neg(&u->z,&u->z);
930        }
931      }
932      else
933      // long z / short b -> z/b
934      {
935        //mpz_set(&u->z,&a->z);
936        mpz_init_set_si(&u->n,SR_TO_INT(b));
937      }
938    }
939// ---------- long / long ------------------------------------
940    else
941    {
942      mpz_set(&u->z,&a->z);
943      mpz_init_set(&u->n,&b->z);
944      if (a->s<2) mpz_mul(&u->n,&u->n,&a->n);
945      if (b->s<2) mpz_mul(&u->z,&u->z,&b->n);
946    }
947  }
948  if (mpz_isNeg(&u->n))
949  {
950    mpz_neg(&u->z,&u->z);
951    mpz_neg(&u->n,&u->n);
952  }
953  if (mpz_cmp_si(&u->n,(long)1)==0)
954  {
955    mpz_clear(&u->n);
956    if (mpz_size1(&u->z)<=MP_SMALL)
957    {
958      int ui=(int)mpz_get_si(&u->z);
959      if ((((ui<<3)>>3)==ui)
960      && (mpz_cmp_si(&u->z,(long)ui)==0))
961      {
962        mpz_clear(&u->z);
963        omFreeBin((ADDRESS)u, rnumber_bin);
964        return INT_TO_SR(ui);
965      }
966    }
967    u->s=3;
968  }
969#ifdef LDEBUG
970  nlTest(u);
971#endif
972  return u;
973}
974
975/*2
976* u:= x ^ exp
977*/
978void nlPower (number x,int exp,number * u)
979{
980  *u = INT_TO_SR(0); // 0^e, e!=0
981  if (!nlIsZero(x))
982  {
983#ifdef LDEBUG
984    nlTest(x);
985#endif
986    number aa=NULL;
987    if (SR_HDL(x) & SR_INT)
988    {
989      aa=nlRInit(SR_TO_INT(x));
990      x=aa;
991    }
992    else if (x->s==0)
993      nlNormalize(x);
994    *u=(number)omAllocBin(rnumber_bin);
995#if defined(LDEBUG)
996    (*u)->debug=123456;
997#endif
998    mpz_init(&(*u)->z);
999    mpz_pow_ui(&(*u)->z,&x->z,(unsigned long)exp);
1000    if (x->s<2)
1001    {
1002      if (mpz_cmp_si(&x->n,(long)1)==0)
1003      {
1004        x->s=3;
1005        mpz_clear(&x->n);
1006      }
1007      else
1008      {
1009        mpz_init(&(*u)->n);
1010        mpz_pow_ui(&(*u)->n,&x->n,(unsigned long)exp);
1011      }
1012    }
1013    (*u)->s = x->s;
1014    if (((*u)->s==3) && (mpz_size1(&(*u)->z)<=MP_SMALL))
1015    {
1016      int ui=(int)mpz_get_si(&(*u)->z);
1017      if ((((ui<<3)>>3)==ui)
1018      && (mpz_cmp_si(&(*u)->z,(long)ui)==0))
1019      {
1020        mpz_clear(&(*u)->z);
1021        omFreeBin((ADDRESS)*u, rnumber_bin);
1022        *u=INT_TO_SR(ui);
1023      }
1024    }
1025    if (aa!=NULL)
1026    {
1027      mpz_clear(&aa->z);
1028      omFreeBin((ADDRESS)aa, rnumber_bin);
1029    }
1030  }
1031  else if (exp==0)
1032    *u = INT_TO_SR(1); // 0^0
1033#ifdef LDEBUG
1034  if (exp<0) Print("nlPower: neg. exp. %d\n",exp);
1035  nlTest(*u);
1036#endif
1037}
1038
1039
1040/*2
1041* za >= 0 ?
1042*/
1043BOOLEAN nlGreaterZero (number a)
1044{
1045#ifdef LDEBUG
1046  nlTest(a);
1047#endif
1048  if (SR_HDL(a) & SR_INT) return SR_HDL(a)>1 /* represents number(0) */;
1049  return (!mpz_isNeg(&a->z));
1050}
1051
1052/*2
1053* a > b ?
1054*/
1055BOOLEAN nlGreater (number a, number b)
1056{
1057#ifdef LDEBUG
1058  nlTest(a);
1059  nlTest(b);
1060#endif
1061  number r;
1062  BOOLEAN rr;
1063  r=nlSub(a,b);
1064  rr=(!nlIsZero(r)) && (nlGreaterZero(r));
1065  nlDelete(&r,currRing);
1066  return rr;
1067}
1068
1069/*2
1070* a == -1 ?
1071*/
1072BOOLEAN nlIsMOne (number a)
1073{
1074#ifdef LDEBUG
1075  if (a==NULL) return FALSE;
1076  nlTest(a);
1077#endif
1078  if (SR_HDL(a) & SR_INT) return (a==INT_TO_SR(-1));
1079  return FALSE;
1080}
1081
1082/*2
1083* result =gcd(a,b)
1084*/
1085number nlGcd(number a, number b, const ring r)
1086{
1087  number result;
1088#ifdef LDEBUG
1089  nlTest(a);
1090  nlTest(b);
1091#endif
1092  //nlNormalize(a);
1093  //nlNormalize(b);
1094  if ((a==INT_TO_SR(1))||(a==INT_TO_SR(-1))
1095  ||  (b==INT_TO_SR(1))||(b==INT_TO_SR(-1)))
1096    return INT_TO_SR(1);
1097  if (a==INT_TO_SR(0)) /* gcd(0,b) ->b */
1098    return nlCopy(b);
1099  if (b==INT_TO_SR(0)) /* gcd(a,0) -> a */
1100    return nlCopy(a);
1101  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
1102  {
1103    int i=SR_TO_INT(a);
1104    int j=SR_TO_INT(b);
1105    if((i==0)||(j==0))
1106      return INT_TO_SR(1);
1107    int l;
1108    i=ABS(i);
1109    j=ABS(j);
1110    do
1111    {
1112      l=i%j;
1113      i=j;
1114      j=l;
1115    } while (l!=0);
1116    return INT_TO_SR(i);
1117  }
1118  if (((!(SR_HDL(a) & SR_INT))&&(a->s<2))
1119  ||  ((!(SR_HDL(b) & SR_INT))&&(b->s<2))) return INT_TO_SR(1);
1120  result=(number)omAllocBin(rnumber_bin);
1121#if defined(LDEBUG)
1122  result->debug=123456;
1123#endif
1124  mpz_init(&result->z);
1125  if (SR_HDL(a) & SR_INT)
1126  {
1127    unsigned long t=mpz_gcd_ui(NULL,&b->z,ABS(SR_TO_INT(a)));
1128    return INT_TO_SR((int)t);
1129  }
1130  else
1131  if (SR_HDL(b) & SR_INT)
1132  {
1133    unsigned long t=mpz_gcd_ui(NULL,&a->z,ABS(SR_TO_INT(b)));
1134    return INT_TO_SR((int)t);
1135  }
1136  else
1137  {
1138    mpz_gcd(&result->z,&a->z,&b->z);
1139  }
1140  result->s = 3;
1141  if (mpz_size1(&result->z)<=MP_SMALL)
1142  {
1143    int ui=(int)mpz_get_si(&result->z);
1144    if ((((ui<<3)>>3)==ui)
1145    && (mpz_cmp_si(&result->z,(long)ui)==0))
1146    {
1147      mpz_clear(&result->z);
1148      omFreeBin((ADDRESS)result, rnumber_bin);
1149      result=INT_TO_SR(ui);
1150    }
1151  }
1152#ifdef LDEBUG
1153  nlTest(result);
1154#endif
1155  return result;
1156}
1157
1158number nlShort1(number x) // assume x->s==0/1
1159{
1160  assume(x->s<2);
1161  if (mpz_cmp_ui(&x->z,(long)0)==0)
1162  {
1163    _nlDelete_NoImm(&x);
1164    return INT_TO_SR(0);
1165  }
1166  if (x->s<2)
1167  {
1168    if (mpz_cmp(&x->z,&x->n)==0)
1169    {
1170      _nlDelete_NoImm(&x);
1171      return INT_TO_SR(1);
1172    }
1173  }
1174  return x;
1175}
1176number nlShort3(number x) // assume x->s==3
1177{
1178  assume(x->s==3);
1179  if ((mpz_cmp_ui(&x->z,(long)0)==0)
1180  || (mpz_size1(&x->z)<=MP_SMALL))
1181  {
1182    int ui=(int)mpz_get_si(&x->z);
1183    if ((((ui<<3)>>3)==ui)
1184    && (mpz_cmp_si(&x->z,(long)ui)==0))
1185    {
1186      mpz_clear(&x->z);
1187      omFreeBin((ADDRESS)x, rnumber_bin);
1188      return INT_TO_SR(ui);
1189    }
1190  }
1191  return x;
1192}
1193/*2
1194* simplify x
1195*/
1196void nlNormalize (number &x)
1197{
1198  if ((SR_HDL(x) & SR_INT) ||(x==NULL))
1199    return;
1200#ifdef LDEBUG
1201  if (!nlTest(x)) { if (x->s!=3) x->s=1; return; }
1202#endif
1203  if (x->s==3)
1204  {
1205    x=nlShort3(x);
1206    return;
1207  }
1208  else if (x->s==0)
1209  {
1210    if (mpz_cmp_si(&x->n,(long)1)==0)
1211    {
1212      mpz_clear(&x->n);
1213      if (mpz_size1(&x->z)<=MP_SMALL)
1214      {
1215        int ui=(int)mpz_get_si(&x->z);
1216        if ((((ui<<3)>>3)==ui)
1217        && (mpz_cmp_si(&x->z,(long)ui)==0))
1218        {
1219          mpz_clear(&x->z);
1220#if defined(LDEBUG)
1221          x->debug=654324;
1222#endif
1223          omFreeBin((ADDRESS)x, rnumber_bin);
1224          x=INT_TO_SR(ui);
1225          return;
1226        }
1227      }
1228      x->s=3;
1229    }
1230    else
1231    {
1232      MP_INT gcd;
1233      mpz_init(&gcd);
1234      mpz_gcd(&gcd,&x->z,&x->n);
1235      x->s=1;
1236      if (mpz_cmp_si(&gcd,(long)1)!=0)
1237      {
1238        MP_INT r;
1239        mpz_init(&r);
1240        MPZ_EXACTDIV(&r,&x->z,&gcd);
1241        mpz_set(&x->z,&r);
1242        MPZ_EXACTDIV(&r,&x->n,&gcd);
1243        mpz_set(&x->n,&r);
1244        mpz_clear(&r);
1245        if (mpz_cmp_si(&x->n,(long)1)==0)
1246        {
1247          mpz_clear(&x->n);
1248          if (mpz_size1(&x->z)<=MP_SMALL)
1249          {
1250            int ui=(int)mpz_get_si(&x->z);
1251            if ((((ui<<3)>>3)==ui)
1252            && (mpz_cmp_si(&x->z,(long)ui)==0))
1253            {
1254              mpz_clear(&x->z);
1255              mpz_clear(&gcd);
1256#if defined(LDEBUG)
1257              x->debug=654324;
1258#endif
1259              omFreeBin((ADDRESS)x, rnumber_bin);
1260              x=INT_TO_SR(ui);
1261              return;
1262            }
1263          }
1264          x->s=3;
1265        }
1266      }
1267      mpz_clear(&gcd);
1268    }
1269  }
1270#ifdef LDEBUG
1271  nlTest(x);
1272#endif
1273}
1274
1275/*2
1276* returns in result->z the lcm(a->z,b->n)
1277*/
1278number nlLcm(number a, number b, const ring r)
1279{
1280  number result;
1281#ifdef LDEBUG
1282  nlTest(a);
1283  nlTest(b);
1284#endif
1285  if ((SR_HDL(b) & SR_INT)
1286  || (b->s==3))
1287  {
1288    // b is 1/(b->n) => b->n is 1 => result is a
1289    return nlCopy(a);
1290  }
1291  result=(number)omAllocBin(rnumber_bin);
1292#if defined(LDEBUG)
1293  result->debug=123456;
1294#endif
1295  result->s=3;
1296  MP_INT gcd;
1297  mpz_init(&gcd);
1298  mpz_init(&result->z);
1299  if (SR_HDL(a) & SR_INT)
1300    mpz_gcd_ui(&gcd,&b->n,ABS(SR_TO_INT(a)));
1301  else
1302    mpz_gcd(&gcd,&a->z,&b->n);
1303  if (mpz_cmp_si(&gcd,(long)1)!=0)
1304  {
1305    MP_INT bt;
1306    mpz_init_set(&bt,&b->n);
1307    MPZ_EXACTDIV(&bt,&bt,&gcd);
1308    if (SR_HDL(a) & SR_INT)
1309      mpz_mul_si(&result->z,&bt,SR_TO_INT(a));
1310    else
1311      mpz_mul(&result->z,&bt,&a->z);
1312    mpz_clear(&bt);
1313  }
1314  else
1315    if (SR_HDL(a) & SR_INT)
1316      mpz_mul_si(&result->z,&b->n,SR_TO_INT(a));
1317    else
1318      mpz_mul(&result->z,&b->n,&a->z);
1319  mpz_clear(&gcd);
1320  if (mpz_size1(&result->z)<=MP_SMALL)
1321  {
1322    int ui=(int)mpz_get_si(&result->z);
1323    if ((((ui<<3)>>3)==ui)
1324    && (mpz_cmp_si(&result->z,(long)ui)==0))
1325    {
1326      mpz_clear(&result->z);
1327      omFreeBin((ADDRESS)result, rnumber_bin);
1328      return INT_TO_SR(ui);
1329    }
1330  }
1331#ifdef LDEBUG
1332  nlTest(result);
1333#endif
1334  return result;
1335}
1336
1337int nlModP(number n, int p)
1338{
1339  if (SR_HDL(n) & SR_INT)
1340  {
1341    int i=SR_TO_INT(n);
1342    if (i<0) return (p-((-i)%p));
1343    return i%p;
1344  }
1345  int iz=(int)mpz_mmod_ui(NULL,&n->z,(unsigned long)p);
1346  if (n->s!=3)
1347  {
1348    int in=mpz_mmod_ui(NULL,&n->n,(unsigned long)p);
1349    #ifdef NV_OPS
1350    if (npPrimeM>NV_MAX_PRIME)
1351    return (int)((long)nvDiv((number)iz,(number)in));
1352    #endif
1353    return (int)((long)npDiv((number)iz,(number)in));
1354  }
1355  return iz;
1356}
1357
1358#ifdef HAVE_RINGS
1359/*2
1360* convert number to GMP and warn if denom != 1
1361*/
1362void nlGMP(number &i, number n)
1363{
1364  // Hier brauche ich einfach die GMP Zahl
1365#ifdef LDEBUG
1366  nlTest(i);
1367#endif
1368  nlNormalize(i);
1369  if (SR_HDL(i) & SR_INT)
1370  {
1371    mpz_set_si((MP_INT*) n, (long) SR_TO_INT(i));
1372    return;
1373  }
1374  if (i->s!=3)
1375  {
1376     WarnS("Omitted denominator during coefficient mapping !");
1377  }
1378  mpz_set((MP_INT*) n, &i->z);
1379}
1380#endif
1381
1382/*2
1383* acces to denominator, other 1 for integers
1384*/
1385number   nlGetDenom(number &n, const ring r)
1386{
1387  if (!(SR_HDL(n) & SR_INT))
1388  {
1389    if (n->s==0)
1390    {
1391      nlNormalize(n);
1392    }
1393    if (!(SR_HDL(n) & SR_INT))
1394    {
1395      if (n->s!=3)
1396      {
1397        number u=(number)omAllocBin(rnumber_bin);
1398        u->s=3;
1399#if defined(LDEBUG)
1400        u->debug=123456;
1401#endif
1402        mpz_init_set(&u->z,&n->n);
1403        {
1404          int ui=(int)mpz_get_si(&u->z);
1405          if ((((ui<<3)>>3)==ui)
1406          && (mpz_cmp_si(&u->z,(long)ui)==0))
1407          {
1408            mpz_clear(&u->z);
1409            omFreeBin((ADDRESS)u, rnumber_bin);
1410            return INT_TO_SR(ui);
1411          }
1412        }
1413        return u;
1414      }
1415    }
1416  }
1417  return INT_TO_SR(1);
1418}
1419
1420/*2
1421* acces to Nominator, nlCopy(n) for integers
1422*/
1423number   nlGetNumerator(number &n, const ring r)
1424{
1425  if (!(SR_HDL(n) & SR_INT))
1426  {
1427    if (n->s==0)
1428    {
1429      nlNormalize(n);
1430    }
1431    if (!(SR_HDL(n) & SR_INT))
1432    {
1433      number u=(number)omAllocBin(rnumber_bin);
1434#if defined(LDEBUG)
1435      u->debug=123456;
1436#endif
1437      u->s=3;
1438      mpz_init_set(&u->z,&n->z);
1439      if (n->s!=3)
1440      {
1441        int ui=(int)mpz_get_si(&u->z);
1442        if ((((ui<<3)>>3)==ui)
1443        && (mpz_cmp_si(&u->z,(long)ui)==0))
1444        {
1445          mpz_clear(&u->z);
1446          omFreeBin((ADDRESS)u, rnumber_bin);
1447          return INT_TO_SR(ui);
1448        }
1449      }
1450      return u;
1451    }
1452  }
1453  return n; // imm. int
1454}
1455
1456/***************************************************************
1457 *
1458 * routines which are needed by Inline(d) routines
1459 *
1460 *******************************************************************/
1461BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b)
1462{
1463  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
1464//  long - short
1465  BOOLEAN bo;
1466  if (SR_HDL(b) & SR_INT)
1467  {
1468    if (a->s!=0) return FALSE;
1469    number n=b; b=a; a=n;
1470  }
1471//  short - long
1472  if (SR_HDL(a) & SR_INT)
1473  {
1474    if (b->s!=0)
1475      return FALSE;
1476    if (((long)a > 0L) && (mpz_isNeg(&b->z)))
1477      return FALSE;
1478    if (((long)a < 0L) && (!mpz_isNeg(&b->z)))
1479      return FALSE;
1480    MP_INT  bb;
1481    mpz_init_set(&bb,&b->n);
1482    mpz_mul_si(&bb,&bb,(long)SR_TO_INT(a));
1483    bo=(mpz_cmp(&bb,&b->z)==0);
1484    mpz_clear(&bb);
1485    return bo;
1486  }
1487// long - long
1488  if (((a->s==1) && (b->s==3))
1489  ||  ((b->s==1) && (a->s==3)))
1490    return FALSE;
1491  if (mpz_isNeg(&a->z)&&(!mpz_isNeg(&b->z)))
1492    return FALSE;
1493  if (mpz_isNeg(&b->z)&&(!mpz_isNeg(&a->z)))
1494    return FALSE;
1495  MP_INT  aa;
1496  MP_INT  bb;
1497  mpz_init_set(&aa,&a->z);
1498  mpz_init_set(&bb,&b->z);
1499  if (a->s<2) mpz_mul(&bb,&bb,&a->n);
1500  if (b->s<2) mpz_mul(&aa,&aa,&b->n);
1501  bo=(mpz_cmp(&aa,&bb)==0);
1502  mpz_clear(&aa);
1503  mpz_clear(&bb);
1504  return bo;
1505}
1506
1507// copy not immediate number a
1508number _nlCopy_NoImm(number a)
1509{
1510  assume(!((SR_HDL(a) & SR_INT)||(a==NULL)));
1511#ifdef LDEBUG
1512  nlTest(a);
1513#endif
1514  number b=(number)omAllocBin(rnumber_bin);
1515#if defined(LDEBUG)
1516  b->debug=123456;
1517#endif
1518  switch (a->s)
1519  {
1520    case 0:
1521    case 1:
1522            mpz_init_set(&b->n,&a->n);
1523    case 3:
1524            mpz_init_set(&b->z,&a->z);
1525            break;
1526  }
1527  b->s = a->s;
1528#ifdef LDEBUG
1529  nlTest(b);
1530#endif
1531  return b;
1532}
1533
1534void _nlDelete_NoImm(number *a)
1535{
1536  {
1537    switch ((*a)->s)
1538    {
1539      case 0:
1540      case 1:
1541        mpz_clear(&(*a)->n);
1542      case 3:
1543        mpz_clear(&(*a)->z);
1544#ifdef LDEBUG
1545        (*a)->s=2;
1546#endif
1547    }
1548    omFreeBin((ADDRESS) *a, rnumber_bin);
1549  }
1550}
1551
1552number _nlNeg_NoImm(number a)
1553{
1554  {
1555    mpz_neg(&a->z,&a->z);
1556    if ((a->s==3) && (mpz_size1(&a->z)<=MP_SMALL))
1557    {
1558      int ui=(int)mpz_get_si(&a->z);
1559      if ((((ui<<3)>>3)==ui)
1560        && (mpz_cmp_si(&a->z,(long)ui)==0))
1561      {
1562        mpz_clear(&a->z);
1563        omFreeBin((ADDRESS)a, rnumber_bin);
1564        a=INT_TO_SR(ui);
1565      }
1566    }
1567  }
1568#ifdef LDEBUG
1569  nlTest(a);
1570#endif
1571  return a;
1572}
1573
1574number _nlAdd_aNoImm_OR_bNoImm(number a, number b)
1575{
1576  number u=(number)omAllocBin(rnumber_bin);
1577#if defined(LDEBUG)
1578  u->debug=123456;
1579#endif
1580  mpz_init(&u->z);
1581  if (SR_HDL(b) & SR_INT)
1582  {
1583    number x=a;
1584    a=b;
1585    b=x;
1586  }
1587  if (SR_HDL(a) & SR_INT)
1588  {
1589    switch (b->s)
1590    {
1591      case 0:
1592      case 1:/* a:short, b:1 */
1593      {
1594        MP_INT x;
1595        mpz_init(&x);
1596        mpz_mul_si(&x,&b->n,SR_TO_INT(a));
1597        mpz_add(&u->z,&b->z,&x);
1598        mpz_clear(&x);
1599        if (mpz_cmp_ui(&u->z,(long)0)==0)
1600        {
1601          mpz_clear(&u->z);
1602          omFreeBin((ADDRESS)u, rnumber_bin);
1603          return INT_TO_SR(0);
1604        }
1605        if (mpz_cmp(&u->z,&b->n)==0)
1606        {
1607          mpz_clear(&u->z);
1608          omFreeBin((ADDRESS)u, rnumber_bin);
1609          return INT_TO_SR(1);
1610        }
1611        mpz_init_set(&u->n,&b->n);
1612        u->s = 0;
1613        break;
1614      }
1615      case 3:
1616      {
1617        if ((long)a>0L)
1618          mpz_add_ui(&u->z,&b->z,SR_TO_INT(a));
1619        else
1620          mpz_sub_ui(&u->z,&b->z,-SR_TO_INT(a));
1621        if (mpz_cmp_ui(&u->z,(long)0)==0)
1622        {
1623          mpz_clear(&u->z);
1624          omFreeBin((ADDRESS)u, rnumber_bin);
1625          return INT_TO_SR(0);
1626        }
1627        //u->s = 3;
1628        if (mpz_size1(&u->z)<=MP_SMALL)
1629        {
1630          int ui=(int)mpz_get_si(&u->z);
1631          if ((((ui<<3)>>3)==ui)
1632          && (mpz_cmp_si(&u->z,(long)ui)==0))
1633          {
1634            mpz_clear(&u->z);
1635            omFreeBin((ADDRESS)u, rnumber_bin);
1636            return INT_TO_SR(ui);
1637          }
1638        }
1639        u->s = 3;
1640        break;
1641      }
1642    }
1643  }
1644  else
1645  {
1646    switch (a->s)
1647    {
1648      case 0:
1649      case 1:
1650      {
1651        switch(b->s)
1652        {
1653          case 0:
1654          case 1:
1655          {
1656            MP_INT x;
1657            mpz_init(&x);
1658
1659            mpz_mul(&x,&b->z,&a->n);
1660            mpz_mul(&u->z,&a->z,&b->n);
1661            mpz_add(&u->z,&u->z,&x);
1662            mpz_clear(&x);
1663
1664            if (mpz_cmp_ui(&u->z,(long)0)==0)
1665            {
1666              mpz_clear(&u->z);
1667              omFreeBin((ADDRESS)u, rnumber_bin);
1668              return INT_TO_SR(0);
1669            }
1670            mpz_init(&u->n);
1671            mpz_mul(&u->n,&a->n,&b->n);
1672            if (mpz_cmp(&u->z,&u->n)==0)
1673            {
1674               mpz_clear(&u->z);
1675               mpz_clear(&u->n);
1676               omFreeBin((ADDRESS)u, rnumber_bin);
1677               return INT_TO_SR(1);
1678            }
1679            u->s = 0;
1680            break;
1681          }
1682          case 3: /* a:1 b:3 */
1683          {
1684            mpz_mul(&u->z,&b->z,&a->n);
1685            mpz_add(&u->z,&u->z,&a->z);
1686            if (mpz_cmp_ui(&u->z,(long)0)==0)
1687            {
1688              mpz_clear(&u->z);
1689              omFreeBin((ADDRESS)u, rnumber_bin);
1690              return INT_TO_SR(0);
1691            }
1692            if (mpz_cmp(&u->z,&a->n)==0)
1693            {
1694              mpz_clear(&u->z);
1695              omFreeBin((ADDRESS)u, rnumber_bin);
1696              return INT_TO_SR(1);
1697            }
1698            mpz_init_set(&u->n,&a->n);
1699            u->s = 0;
1700            break;
1701          }
1702        } /*switch (b->s) */
1703        break;
1704      }
1705      case 3:
1706      {
1707        switch(b->s)
1708        {
1709          case 0:
1710          case 1:/* a:3, b:1 */
1711          {
1712            mpz_mul(&u->z,&a->z,&b->n);
1713            mpz_add(&u->z,&u->z,&b->z);
1714            if (mpz_cmp_ui(&u->z,(long)0)==0)
1715            {
1716              mpz_clear(&u->z);
1717              omFreeBin((ADDRESS)u, rnumber_bin);
1718              return INT_TO_SR(0);
1719            }
1720            if (mpz_cmp(&u->z,&b->n)==0)
1721            {
1722              mpz_clear(&u->z);
1723              omFreeBin((ADDRESS)u, rnumber_bin);
1724              return INT_TO_SR(1);
1725            }
1726            mpz_init_set(&u->n,&b->n);
1727            u->s = 0;
1728            break;
1729          }
1730          case 3:
1731          {
1732            mpz_add(&u->z,&a->z,&b->z);
1733            if (mpz_cmp_ui(&u->z,(long)0)==0)
1734            {
1735              mpz_clear(&u->z);
1736              omFreeBin((ADDRESS)u, rnumber_bin);
1737              return INT_TO_SR(0);
1738            }
1739            if (mpz_size1(&u->z)<=MP_SMALL)
1740            {
1741              int ui=(int)mpz_get_si(&u->z);
1742              if ((((ui<<3)>>3)==ui)
1743              && (mpz_cmp_si(&u->z,(long)ui)==0))
1744              {
1745                mpz_clear(&u->z);
1746                omFreeBin((ADDRESS)u, rnumber_bin);
1747                return INT_TO_SR(ui);
1748              }
1749            }
1750            u->s = 3;
1751            break;
1752          }
1753        }
1754        break;
1755      }
1756    }
1757  }
1758#ifdef LDEBUG
1759  nlTest(u);
1760#endif
1761  return u;
1762}
1763
1764number _nlSub_aNoImm_OR_bNoImm(number a, number b)
1765{
1766  number u=(number)omAllocBin(rnumber_bin);
1767#if defined(LDEBUG)
1768  u->debug=123456;
1769#endif
1770  mpz_init(&u->z);
1771  if (SR_HDL(a) & SR_INT)
1772  {
1773    switch (b->s)
1774    {
1775      case 0:
1776      case 1:/* a:short, b:1 */
1777      {
1778        MP_INT x;
1779        mpz_init(&x);
1780        mpz_mul_si(&x,&b->n,SR_TO_INT(a));
1781        mpz_sub(&u->z,&x,&b->z);
1782        mpz_clear(&x);
1783        if (mpz_cmp_ui(&u->z,(long)0)==0)
1784        {
1785          mpz_clear(&u->z);
1786          omFreeBin((ADDRESS)u, rnumber_bin);
1787          return INT_TO_SR(0);
1788        }
1789        if (mpz_cmp(&u->z,&b->n)==0)
1790        {
1791          mpz_clear(&u->z);
1792          omFreeBin((ADDRESS)u, rnumber_bin);
1793          return INT_TO_SR(1);
1794        }
1795        mpz_init_set(&u->n,&b->n);
1796        u->s = 0;
1797        break;
1798      }
1799      case 3:
1800      {
1801        if ((long)a>0L)
1802        {
1803          mpz_sub_ui(&u->z,&b->z,SR_TO_INT(a));
1804          mpz_neg(&u->z,&u->z);
1805        }
1806        else
1807        {
1808          mpz_add_ui(&u->z,&b->z,-SR_TO_INT(a));
1809          mpz_neg(&u->z,&u->z);
1810        }
1811        if (mpz_cmp_ui(&u->z,(long)0)==0)
1812        {
1813          mpz_clear(&u->z);
1814          omFreeBin((ADDRESS)u, rnumber_bin);
1815          return INT_TO_SR(0);
1816        }
1817        if (mpz_size1(&u->z)<=MP_SMALL)
1818        {
1819          int ui=(int)mpz_get_si(&u->z);
1820          if ((((ui<<3)>>3)==ui)
1821          && (mpz_cmp_si(&u->z,(long)ui)==0))
1822          {
1823            mpz_clear(&u->z);
1824            omFreeBin((ADDRESS)u, rnumber_bin);
1825            return INT_TO_SR(ui);
1826          }
1827        }
1828        u->s = 3;
1829        break;
1830      }
1831    }
1832  }
1833  else if (SR_HDL(b) & SR_INT)
1834  {
1835    switch (a->s)
1836    {
1837      case 0:
1838      case 1:/* b:short, a:1 */
1839      {
1840        MP_INT x;
1841        mpz_init(&x);
1842        mpz_mul_si(&x,&a->n,SR_TO_INT(b));
1843        mpz_sub(&u->z,&a->z,&x);
1844        mpz_clear(&x);
1845        if (mpz_cmp_ui(&u->z,(long)0)==0)
1846        {
1847          mpz_clear(&u->z);
1848          omFreeBin((ADDRESS)u, rnumber_bin);
1849          return INT_TO_SR(0);
1850        }
1851        if (mpz_cmp(&u->z,&a->n)==0)
1852        {
1853          mpz_clear(&u->z);
1854          omFreeBin((ADDRESS)u, rnumber_bin);
1855          return INT_TO_SR(1);
1856        }
1857        mpz_init_set(&u->n,&a->n);
1858        u->s = 0;
1859        break;
1860      }
1861      case 3:
1862      {
1863        if ((long)b>0L)
1864        {
1865          mpz_sub_ui(&u->z,&a->z,SR_TO_INT(b));
1866        }
1867        else
1868        {
1869          mpz_add_ui(&u->z,&a->z,-SR_TO_INT(b));
1870        }
1871        if (mpz_cmp_ui(&u->z,(long)0)==0)
1872        {
1873          mpz_clear(&u->z);
1874          omFreeBin((ADDRESS)u, rnumber_bin);
1875          return INT_TO_SR(0);
1876        }
1877        //u->s = 3;
1878        if (mpz_size1(&u->z)<=MP_SMALL)
1879        {
1880          int ui=(int)mpz_get_si(&u->z);
1881          if ((((ui<<3)>>3)==ui)
1882          && (mpz_cmp_si(&u->z,(long)ui)==0))
1883          {
1884            mpz_clear(&u->z);
1885            omFreeBin((ADDRESS)u, rnumber_bin);
1886            return INT_TO_SR(ui);
1887          }
1888        }
1889        u->s = 3;
1890        break;
1891      }
1892    }
1893  }
1894  else
1895  {
1896    switch (a->s)
1897    {
1898      case 0:
1899      case 1:
1900      {
1901        switch(b->s)
1902        {
1903          case 0:
1904          case 1:
1905          {
1906            MP_INT x;
1907            MP_INT y;
1908            mpz_init(&x);
1909            mpz_init(&y);
1910            mpz_mul(&x,&b->z,&a->n);
1911            mpz_mul(&y,&a->z,&b->n);
1912            mpz_sub(&u->z,&y,&x);
1913            mpz_clear(&x);
1914            mpz_clear(&y);
1915            if (mpz_cmp_ui(&u->z,(long)0)==0)
1916            {
1917              mpz_clear(&u->z);
1918              omFreeBin((ADDRESS)u, rnumber_bin);
1919              return INT_TO_SR(0);
1920            }
1921            mpz_init(&u->n);
1922            mpz_mul(&u->n,&a->n,&b->n);
1923            if (mpz_cmp(&u->z,&u->n)==0)
1924            {
1925              mpz_clear(&u->z);
1926              mpz_clear(&u->n);
1927              omFreeBin((ADDRESS)u, rnumber_bin);
1928              return INT_TO_SR(1);
1929            }
1930            u->s = 0;
1931            break;
1932          }
1933          case 3: /* a:1, b:3 */
1934          {
1935            MP_INT x;
1936            mpz_init(&x);
1937            mpz_mul(&x,&b->z,&a->n);
1938            mpz_sub(&u->z,&a->z,&x);
1939            mpz_clear(&x);
1940            if (mpz_cmp_ui(&u->z,(long)0)==0)
1941            {
1942              mpz_clear(&u->z);
1943              omFreeBin((ADDRESS)u, rnumber_bin);
1944              return INT_TO_SR(0);
1945            }
1946            if (mpz_cmp(&u->z,&a->n)==0)
1947            {
1948              mpz_clear(&u->z);
1949              omFreeBin((ADDRESS)u, rnumber_bin);
1950              return INT_TO_SR(1);
1951            }
1952            mpz_init_set(&u->n,&a->n);
1953            u->s = 0;
1954            break;
1955          }
1956        }
1957        break;
1958      }
1959      case 3:
1960      {
1961        switch(b->s)
1962        {
1963          case 0:
1964          case 1: /* a:3, b:1 */
1965          {
1966            MP_INT x;
1967            mpz_init(&x);
1968            mpz_mul(&x,&a->z,&b->n);
1969            mpz_sub(&u->z,&x,&b->z);
1970            mpz_clear(&x);
1971            if (mpz_cmp_ui(&u->z,(long)0)==0)
1972            {
1973              mpz_clear(&u->z);
1974              omFreeBin((ADDRESS)u, rnumber_bin);
1975              return INT_TO_SR(0);
1976            }
1977            if (mpz_cmp(&u->z,&b->n)==0)
1978            {
1979              mpz_clear(&u->z);
1980              omFreeBin((ADDRESS)u, rnumber_bin);
1981              return INT_TO_SR(1);
1982            }
1983            mpz_init_set(&u->n,&b->n);
1984            u->s = 0;
1985            break;
1986          }
1987          case 3: /* a:3 , b:3 */
1988          {
1989            mpz_sub(&u->z,&a->z,&b->z);
1990            if (mpz_cmp_ui(&u->z,(long)0)==0)
1991            {
1992              mpz_clear(&u->z);
1993              omFreeBin((ADDRESS)u, rnumber_bin);
1994              return INT_TO_SR(0);
1995            }
1996            //u->s = 3;
1997            if (mpz_size1(&u->z)<=MP_SMALL)
1998            {
1999              int ui=(int)mpz_get_si(&u->z);
2000              if ((((ui<<3)>>3)==ui)
2001              && (mpz_cmp_si(&u->z,(long)ui)==0))
2002              {
2003                mpz_clear(&u->z);
2004                omFreeBin((ADDRESS)u, rnumber_bin);
2005                return INT_TO_SR(ui);
2006              }
2007            }
2008            u->s = 3;
2009            break;
2010          }
2011        }
2012        break;
2013      }
2014    }
2015  }
2016#ifdef LDEBUG
2017  nlTest(u);
2018#endif
2019  return u;
2020}
2021
2022// a and b are intermediate, but a*b not
2023number _nlMult_aImm_bImm_rNoImm(number a, number b)
2024{
2025  number u=(number)omAllocBin(rnumber_bin);
2026#if defined(LDEBUG)
2027  u->debug=123456;
2028#endif
2029  u->s=3;
2030  mpz_init_set_si(&u->z,(long)SR_TO_INT(a));
2031  mpz_mul_si(&u->z,&u->z,(long)SR_TO_INT(b));
2032#ifdef LDEBUG
2033  nlTest(u);
2034#endif
2035  return u;
2036}
2037
2038// a or b are not immediate
2039number _nlMult_aNoImm_OR_bNoImm(number a, number b)
2040{
2041  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
2042  number u=(number)omAllocBin(rnumber_bin);
2043#if defined(LDEBUG)
2044  u->debug=123456;
2045#endif
2046  mpz_init(&u->z);
2047  if (SR_HDL(b) & SR_INT)
2048  {
2049    number x=a;
2050    a=b;
2051    b=x;
2052  }
2053  if (SR_HDL(a) & SR_INT)
2054  {
2055    u->s=b->s;
2056    if (u->s==1) u->s=0;
2057    if ((long)a>0L)
2058    {
2059      mpz_mul_ui(&u->z,&b->z,(unsigned long)SR_TO_INT(a));
2060    }
2061    else
2062    {
2063      if (a==INT_TO_SR(-1))
2064      {
2065        mpz_set(&u->z,&b->z);
2066        mpz_neg(&u->z,&u->z);
2067        u->s=b->s;
2068      }
2069      else
2070      {
2071        mpz_mul_ui(&u->z,&b->z,(unsigned long)-SR_TO_INT(a));
2072        mpz_neg(&u->z,&u->z);
2073      }
2074    }
2075    if (u->s<2)
2076    {
2077      if (mpz_cmp(&u->z,&b->n)==0)
2078      {
2079        mpz_clear(&u->z);
2080        omFreeBin((ADDRESS)u, rnumber_bin);
2081        return INT_TO_SR(1);
2082      }
2083      mpz_init_set(&u->n,&b->n);
2084    }
2085    else //u->s==3
2086    {
2087      if (mpz_size1(&u->z)<=MP_SMALL)
2088      {
2089        int ui=(int)mpz_get_si(&u->z);
2090        if ((((ui<<3)>>3)==ui)
2091            && (mpz_cmp_si(&u->z,(long)ui)==0))
2092        {
2093          mpz_clear(&u->z);
2094          omFreeBin((ADDRESS)u, rnumber_bin);
2095          return INT_TO_SR(ui);
2096        }
2097      }
2098    }
2099  }
2100  else
2101  {
2102    mpz_mul(&u->z,&a->z,&b->z);
2103    u->s = 0;
2104    if(a->s==3)
2105    {
2106      if(b->s==3)
2107      {
2108        u->s = 3;
2109      }
2110      else
2111      {
2112        if (mpz_cmp(&u->z,&b->n)==0)
2113        {
2114          mpz_clear(&u->z);
2115          omFreeBin((ADDRESS)u, rnumber_bin);
2116          return INT_TO_SR(1);
2117        }
2118        mpz_init_set(&u->n,&b->n);
2119      }
2120    }
2121    else
2122    {
2123      if(b->s==3)
2124      {
2125        if (mpz_cmp(&u->z,&a->n)==0)
2126        {
2127          mpz_clear(&u->z);
2128          omFreeBin((ADDRESS)u, rnumber_bin);
2129          return INT_TO_SR(1);
2130        }
2131        mpz_init_set(&u->n,&a->n);
2132      }
2133      else
2134      {
2135        mpz_init(&u->n);
2136        mpz_mul(&u->n,&a->n,&b->n);
2137        if (mpz_cmp(&u->z,&u->n)==0)
2138        {
2139          mpz_clear(&u->z);
2140          mpz_clear(&u->n);
2141          omFreeBin((ADDRESS)u, rnumber_bin);
2142          return INT_TO_SR(1);
2143        }
2144      }
2145    }
2146  }
2147#ifdef LDEBUG
2148  nlTest(u);
2149#endif
2150  return u;
2151}
2152
2153/*2
2154* z := i
2155*/
2156number nlRInit (int i)
2157{
2158  number z=(number)omAllocBin(rnumber_bin);
2159#if defined(LDEBUG)
2160  z->debug=123456;
2161#endif
2162  mpz_init_set_si(&z->z,(long)i);
2163  z->s = 3;
2164  return z;
2165}
2166
2167/*2
2168* z := i/j
2169*/
2170number nlInit2 (int i, int j)
2171{
2172  number z=(number)omAllocBin(rnumber_bin);
2173#if defined(LDEBUG)
2174  z->debug=123456;
2175#endif
2176  mpz_init_set_si(&z->z,(long)i);
2177  mpz_init_set_si(&z->n,(long)j);
2178  z->s = 0;
2179  nlNormalize(z);
2180  return z;
2181}
2182
2183number nlInit2gmp (mpz_t i, mpz_t j)
2184{
2185  number z=(number)omAllocBin(rnumber_bin);
2186#if defined(LDEBUG)
2187  z->debug=123456;
2188#endif
2189  mpz_init_set(&z->z,i);
2190  mpz_init_set(&z->n,j);
2191  z->s = 0;
2192  nlNormalize(z);
2193  return z;
2194}
2195
2196#else // DO_LINLINE
2197
2198// declare immedate routines
2199number nlRInit (int i);
2200BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b);
2201number  _nlCopy_NoImm(number a);
2202number  _nlNeg_NoImm(number a);
2203number  _nlAdd_aNoImm_OR_bNoImm(number a, number b);
2204number  _nlSub_aNoImm_OR_bNoImm(number a, number b);
2205number  _nlMult_aNoImm_OR_bNoImm(number a, number b);
2206number  _nlMult_aImm_bImm_rNoImm(number a, number b);
2207
2208#endif
2209
2210/***************************************************************
2211 *
2212 * Routines which might be inlined by p_Numbers.h
2213 *
2214 *******************************************************************/
2215#if defined(DO_LINLINE) || !defined(P_NUMBERS_H)
2216
2217// routines which are always inlined/static
2218
2219/*2
2220* a = b ?
2221*/
2222LINLINE BOOLEAN nlEqual (number a, number b)
2223{
2224#ifdef LDEBUG
2225  nlTest(a);
2226  nlTest(b);
2227#endif
2228// short - short
2229  if (SR_HDL(a) & SR_HDL(b) & SR_INT) return a==b;
2230  return _nlEqual_aNoImm_OR_bNoImm(a, b);
2231}
2232
2233
2234LINLINE number nlInit (int i)
2235{
2236  number n;
2237  if ( ((i << 3) >> 3) == i ) n=INT_TO_SR(i);
2238  else                        n=nlRInit(i);
2239#ifdef LDEBUG
2240  nlTest(n);
2241#endif
2242  return n;
2243}
2244
2245
2246/*2
2247* a == 1 ?
2248*/
2249LINLINE BOOLEAN nlIsOne (number a)
2250{
2251#ifdef LDEBUG
2252  if (a==NULL) return FALSE;
2253  nlTest(a);
2254#endif
2255  if (SR_HDL(a) & SR_INT) return (a==INT_TO_SR(1));
2256  return FALSE;
2257}
2258
2259LINLINE BOOLEAN nlIsZero (number a)
2260{
2261  return (a==INT_TO_SR(0));
2262  //return (mpz_cmp_si(&a->z,(long)0)==0);
2263}
2264
2265/*2
2266* copy a to b
2267*/
2268LINLINE number nlCopy(number a)
2269{
2270  if ((SR_HDL(a) & SR_INT)||(a==NULL))
2271  {
2272    return a;
2273  }
2274  return _nlCopy_NoImm(a);
2275}
2276
2277
2278LINLINE void nlNew (number * r)
2279{
2280  *r=NULL;
2281}
2282
2283/*2
2284* delete a
2285*/
2286LINLINE void nlDelete (number * a, const ring r)
2287{
2288  if (*a!=NULL)
2289  {
2290#ifdef LDEBUG
2291    nlTest(*a);
2292#endif
2293    if ((SR_HDL(*a) & SR_INT)==0)
2294    {
2295      _nlDelete_NoImm(a);
2296    }
2297    *a=NULL;
2298  }
2299}
2300
2301/*2
2302* za:= - za
2303*/
2304LINLINE number nlNeg (number a)
2305{
2306#ifdef LDEBUG
2307  nlTest(a);
2308#endif
2309  if(SR_HDL(a) &SR_INT)
2310  {
2311    int r=SR_TO_INT(a);
2312    if (r==(-(1<<28))) a=nlRInit(1<<28);
2313    else               a=INT_TO_SR(-r);
2314    return a;
2315  }
2316  return _nlNeg_NoImm(a);
2317}
2318
2319/*2
2320* u:= a + b
2321*/
2322LINLINE number nlAdd (number a, number b)
2323{
2324  number u;
2325  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2326  {
2327    int r=SR_HDL(a)+SR_HDL(b)-1;
2328    if ( ((r << 1) >> 1) == r )
2329      return (number)(long)r;
2330    else
2331      return nlRInit(SR_TO_INT(r));
2332  }
2333  return _nlAdd_aNoImm_OR_bNoImm(a, b);
2334}
2335
2336number nlShort1(number a);
2337number nlShort3(number a);
2338
2339LINLINE number nlInpAdd (number a, number b, const ring r)
2340{
2341  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2342  {
2343    int r=SR_HDL(a)+SR_HDL(b)-1;
2344    if ( ((r << 1) >> 1) == r )
2345      return (number)(long)r;
2346    else
2347      return nlRInit(SR_TO_INT(r));
2348  }
2349  // a=a+b
2350  if (SR_HDL(b) & SR_INT)
2351  {
2352    switch (a->s)
2353    {
2354      case 0:
2355      case 1:/* b:short, a:1 */
2356      {
2357        MP_INT x;
2358        mpz_init(&x);
2359        mpz_mul_si(&x,&a->n,SR_TO_INT(b));
2360        mpz_add(&a->z,&a->z,&x);
2361        mpz_clear(&x);
2362        a->s = 0;
2363        a=nlShort1(a);
2364        break;
2365      }
2366      case 3:
2367      {
2368        if ((long)b>0L)
2369          mpz_add_ui(&a->z,&a->z,SR_TO_INT(b));
2370        else
2371          mpz_sub_ui(&a->z,&a->z,-SR_TO_INT(b));
2372        a->s = 3;
2373        a=nlShort3(a);
2374        //nlNormalize(a);
2375        break;
2376      }
2377    }
2378    return a;
2379  }
2380  if (SR_HDL(a) & SR_INT)
2381  {
2382    number u=(number)omAllocBin(rnumber_bin);
2383    #if defined(LDEBUG)
2384    u->debug=123456;
2385    #endif
2386    mpz_init(&u->z);
2387    switch (b->s)
2388    {
2389      case 0:
2390      case 1:/* a:short, b:1 */
2391      {
2392        MP_INT x;
2393        mpz_init(&x);
2394
2395        mpz_mul_si(&x,&b->n,SR_TO_INT(a));
2396        mpz_add(&u->z,&b->z,&x);
2397        mpz_clear(&x);
2398        // result cannot be 0, if coeffs are normalized
2399        mpz_init_set(&u->n,&b->n);
2400        u->s = 0;
2401        u=nlShort1(u);
2402        break;
2403      }
2404      case 3:
2405      {
2406        if ((long)a>0L)
2407          mpz_add_ui(&u->z,&b->z,SR_TO_INT(a));
2408        else
2409          mpz_sub_ui(&u->z,&b->z,-SR_TO_INT(a));
2410        // result cannot be 0, if coeffs are normalized
2411        u->s = 3;
2412        u=nlShort3(u);
2413        break;
2414      }
2415    }
2416    #ifdef LDEBUG
2417    nlTest(u);
2418    #endif
2419    return u;
2420  }
2421  else
2422  {
2423    switch (a->s)
2424    {
2425      case 0:
2426      case 1:
2427      {
2428        switch(b->s)
2429        {
2430          case 0:
2431          case 1: /* a:1 b:1 */
2432          {
2433            MP_INT x;
2434            MP_INT y;
2435            mpz_init(&x);
2436            mpz_init(&y);
2437            mpz_mul(&x,&b->z,&a->n);
2438            mpz_mul(&y,&a->z,&b->n);
2439            mpz_add(&a->z,&x,&y);
2440            mpz_clear(&x);
2441            mpz_clear(&y);
2442            mpz_mul(&a->n,&a->n,&b->n);
2443            a->s = 0;
2444            break;
2445          }
2446          case 3: /* a:1 b:3 */
2447          {
2448            MP_INT x;
2449            mpz_init(&x);
2450            mpz_mul(&x,&b->z,&a->n);
2451            mpz_add(&a->z,&a->z,&x);
2452            mpz_clear(&x);
2453            a->s = 0;
2454            break;
2455          }
2456        } /*switch (b->s) */
2457        a=nlShort1(a);
2458        break;
2459      }
2460      case 3:
2461      {
2462        switch(b->s)
2463        {
2464          case 0:
2465          case 1:/* a:3, b:1 */
2466          {
2467            MP_INT x;
2468            mpz_init(&x);
2469            mpz_mul(&x,&a->z,&b->n);
2470            mpz_add(&a->z,&b->z,&x);
2471            mpz_clear(&x);
2472            mpz_init_set(&a->n,&b->n);
2473            a->s = 0;
2474            a=nlShort1(a);
2475            break;
2476          }
2477          case 3:
2478          {
2479            mpz_add(&a->z,&a->z,&b->z);
2480            a->s = 3;
2481            a=nlShort3(a);
2482            break;
2483          }
2484        }
2485        break;
2486      }
2487    }
2488    #ifdef LDEBUG
2489    nlTest(a);
2490    #endif
2491    return a;
2492  }
2493}
2494
2495LINLINE number nlMult (number a, number b)
2496{
2497#ifdef LDEBUG
2498  nlTest(a);
2499  nlTest(b);
2500#endif
2501  if (a==INT_TO_SR(0)) return INT_TO_SR(0);
2502  if (b==INT_TO_SR(0)) return INT_TO_SR(0);
2503  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2504  {
2505    int r=(SR_HDL(a)-1)*(SR_HDL(b)>>1);
2506    if ((r/(SR_HDL(b)>>1))==(SR_HDL(a)-1))
2507    {
2508      number u=((number) ((r>>1)+SR_INT));
2509      if (((SR_HDL(u)<<1)>>1)==SR_HDL(u)) return (u);
2510      return nlRInit(SR_HDL(u)>>2);
2511    }
2512    return _nlMult_aImm_bImm_rNoImm(a, b);
2513  }
2514  return _nlMult_aNoImm_OR_bNoImm(a, b);
2515}
2516
2517
2518/*2
2519* u:= a - b
2520*/
2521LINLINE number nlSub (number a, number b)
2522{
2523  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2524  {
2525    int r=SR_HDL(a)-SR_HDL(b)+1;
2526    if ( ((r << 1) >> 1) == r )
2527    {
2528      return (number)r;
2529    }
2530    else
2531      return nlRInit(SR_TO_INT(r));
2532  }
2533  return _nlSub_aNoImm_OR_bNoImm(a, b);
2534}
2535
2536#endif // DO_LINLINE
2537
2538#ifndef P_NUMBERS_H
2539
2540void nlInpGcd(number &a, number b, const ring r)
2541{
2542  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2543  {
2544    number n=nlGcd(a,b,r);
2545    nlDelete(&a,r);
2546    a=n;
2547  }
2548  else
2549  {
2550    mpz_gcd(&a->z,&a->z,&b->z);
2551    if (mpz_size1(&a->z)<=MP_SMALL)
2552    {
2553      int ui=(int)mpz_get_si(&a->z);
2554      if ((((ui<<3)>>3)==ui)
2555      && (mpz_cmp_si(&a->z,(long)ui)==0))
2556      {
2557        mpz_clear(&a->z);
2558        omFreeBin((ADDRESS)a, rnumber_bin);
2559        a=INT_TO_SR(ui);
2560      }
2561    }
2562  }
2563}
2564void nlInpIntDiv(number &a, number b, const ring r)
2565{
2566  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2567  {
2568    number n=nlIntDiv(a,b);
2569    nlDelete(&a,r);
2570    a=n;
2571  }
2572  else
2573  {
2574    if (mpz_isNeg(&a->z))
2575    {
2576      if (mpz_isNeg(&b->z))
2577      {
2578        mpz_add(&a->z,&a->z,&b->z);
2579      }
2580      else
2581      {
2582        mpz_sub(&a->z,&a->z,&b->z);
2583      }
2584      mpz_add_ui(&a->z,&a->z,1);
2585    }
2586    else
2587    {
2588      if (mpz_isNeg(&b->z))
2589      {
2590        mpz_sub(&a->z,&a->z,&b->z);
2591      }
2592      else
2593      {
2594        mpz_add(&a->z,&a->z,&b->z);
2595      }
2596      mpz_sub_ui(&a->z,&a->z,1);
2597    }
2598    MPZ_DIV(&a->z,&a->z,&b->z);
2599    if (mpz_size1(&a->z)<=MP_SMALL)
2600    {
2601      int ui=(int)mpz_get_si(&a->z);
2602      if ((((ui<<3)>>3)==ui)
2603      && (mpz_cmp_si(&a->z,(long)ui)==0))
2604      {
2605        mpz_clear(&a->z);
2606        omFreeBin((ADDRESS)a, rnumber_bin);
2607        a=INT_TO_SR(ui);
2608      }
2609    }
2610  }
2611}
2612void nlInpMult(number &a, number b, const ring r)
2613{
2614  if (((SR_HDL(b)|SR_HDL(a))&SR_INT)
2615  )
2616  {
2617    number n=nlMult(a,b);
2618    nlDelete(&a,r);
2619    a=n;
2620  }
2621  else
2622  {
2623    mpz_mul(&a->z,&a->z,&b->z);
2624    if (a->s==3)
2625    {
2626      if(b->s!=3)
2627      {
2628        mpz_init_set(&a->n,&b->n);
2629        a->s=0;
2630      }
2631    }
2632    else
2633    {
2634      if(b->s!=3)
2635      {
2636        mpz_mul(&a->n,&a->n,&b->n);
2637      }
2638      a->s=0;
2639    }
2640  }
2641}
2642
2643#if 0
2644number nlMod(number a, number b)
2645{
2646  if (((SR_HDL(b)&SR_HDL(a))&SR_INT)
2647  {
2648    int bi=SR_TO_INT(b);
2649    int ai=SR_TO_INT(a);
2650    int bb=ABS(bi);
2651    int c=ai%bb;
2652    if (c<0)  c+=bb;
2653    return (INT_TO_SR(c));
2654  }
2655  number al;
2656  number bl;
2657  if (SR_HDL(a))&SR_INT)
2658    al=nlRInit(SR_TO_INT(a));
2659  else
2660    al=nlCopy(a);
2661  if (SR_HDL(b))&SR_INT)
2662    bl=nlRInit(SR_TO_INT(b));
2663  else
2664    bl=nlCopy(b);
2665  number r=nlRInit(0);
2666  mpz_mod(r->z,al->z,bl->z);
2667  nlDelete(&al);
2668  nlDelete(&bl);
2669  if (mpz_size1(&r->z)<=MP_SMALL)
2670  {
2671    int ui=(int)mpz_get_si(&r->z);
2672    if ((((ui<<3)>>3)==ui)
2673    && (mpz_cmp_si(&x->z,(long)ui)==0))
2674    {
2675      mpz_clear(&r->z);
2676      omFreeBin((ADDRESS)r, rnumber_bin);
2677      r=INT_TO_SR(ui);
2678    }
2679  }
2680  return r;
2681}
2682#endif
2683#endif // not P_NUMBERS_H
2684#endif // LONGRAT_CC
Note: See TracBrowser for help on using the repository browser.