source: git/kernel/longrat.cc @ 83f8aff

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