source: git/kernel/longrat.cc @ f553f3

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