source: git/kernel/longrat.cc @ b7e838

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