source: git/kernel/longrat.cc @ 35aab3

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