source: git/kernel/longrat.cc @ 8627ad

spielwiese
Last change on this file since 8627ad was 6242bb3, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: 0^0 (Q) git-svn-id: file:///usr/local/Singular/svn/trunk@10725 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 50.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: longrat.cc,v 1.30 2008-05-20 15:30:49 Singular Exp $ */
5/*
6* ABSTRACT: computation with long rational numbers (Hubert Grassmann)
7*/
8
9#ifndef LONGRAT_CC
10#define LONGRAT_CC
11
12#include <string.h>
13#include <float.h>
14#include "mod2.h"
15#include "structs.h"
16#include "omalloc.h"
17#include "febase.h"
18#include "numbers.h"
19#include "modulop.h"
20#include "ring.h"
21#include "shortfl.h"
22#include "mpr_complex.h"
23#include "longrat.h"
24
25
26#ifndef BYTES_PER_MP_LIMB
27#define BYTES_PER_MP_LIMB sizeof(mp_limb_t)
28#endif
29
30/*-----------------------------------------------------------------*/
31/*3
32* parameter s in number:
33* 0 (or FALSE): not normalised rational
34* 1 (or TRUE):  normalised rational
35* 3          :  integer with n==NULL
36*/
37/*3
38**  'SR_INT' is the type of those integers small enough to fit into  29  bits.
39**  Therefor the value range of this small integers is: $-2^{28}...2^{28}-1$.
40**
41**  Small integers are represented by an immediate integer handle, containing
42**  the value instead of pointing  to  it,  which  has  the  following  form:
43**
44**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
45**      | guard | sign  | bit   | bit   |       | bit   | tag   | tag   |
46**      | bit   | bit   | 27    | 26    |       | 0     | 0     | 1     |
47**      +-------+-------+-------+-------+- - - -+-------+-------+-------+
48**
49**  Immediate integers handles carry the tag 'SR_INT', i.e. the last bit is 1.
50**  This distuingishes immediate integers from other handles which  point  to
51**  structures aligned on 4 byte boundaries and therefor have last bit  zero.
52**  (The second bit is reserved as tag to allow extensions of  this  scheme.)
53**  Using immediates as pointers and dereferencing them gives address errors.
54**
55**  To aid overflow check the most significant two bits must always be equal,
56**  that is to say that the sign bit of immediate integers has a  guard  bit.
57**
58**  The macros 'INT_TO_SR' and 'SR_TO_INT' should be used to convert  between
59**  a small integer value and its representation as immediate integer handle.
60**
61**  Large integers and rationals are represented by z and n
62**  where n may be undefined (if s==3)
63**  NULL represents only deleted values
64*/
65#define SR_HDL(A) ((long)(A))
66/*#define SR_INT    1L*/
67/*#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))*/
68// #define SR_TO_INT(SR)   (((long)SR) >> 2)
69
70#define MP_SMALL 1
71//#define mpz_isNeg(A) (mpz_cmp_si(A,(long)0)<0)
72#define mpz_isNeg(A) ((A)->_mp_size<0)
73#define mpz_limb_size(A) ((A)->_mp_size)
74#define mpz_limb_d(A) ((A)->_mp_d)
75#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
76#define MPZ_EXACTDIV(A,B,C) mpz_divexact((A),(B),(C))
77
78
79/***************************************************************
80 *
81 * Routines which are never inlined by p_Numbers.h
82 *
83 *******************************************************************/
84#ifndef P_NUMBERS_H
85
86omBin rnumber_bin = omGetSpecBin(sizeof(snumber));
87
88number nlOne=INT_TO_SR(1);
89
90#if (__GNU_MP_VERSION*10+__GNU_MP_VERSION_MINOR < 31)
91void mpz_mul_si (mpz_ptr r, mpz_srcptr s, long int si)
92{
93  if (si>=0)
94    mpz_mul_ui(r,s,si);
95  else
96  {
97    mpz_mul_ui(r,s,-si);
98    mpz_neg(r,r);
99  }
100}
101#endif
102
103static int nlPrimeM;
104static number nlMapP(number from)
105{
106  number to;
107  int save=npPrimeM;
108  npPrimeM=nlPrimeM;
109  to = nlInit(npInt(from));
110  npPrimeM=save;
111  return to;
112}
113
114static number nlMapLongR(number from);
115static number nlMapR(number from);
116
117nMapFunc nlSetMap(ring src, ring dst)
118{
119  if (rField_is_Q(src))
120  {
121    return nlCopy;
122  }
123  if (rField_is_Zp(src))
124  {
125    nlPrimeM=rChar(src);
126    return nlMapP;
127  }
128  if (rField_is_R(src))
129  {
130    return nlMapR;
131  }
132  if (rField_is_long_R(src))
133  {
134    return nlMapLongR; /* long R -> Q */
135  }
136  return NULL;
137}
138
139#ifdef LDEBUG
140BOOLEAN nlDBTest(number a, const char *f,const int l)
141{
142  if (a==NULL)
143  {
144    Print("!!longrat: NULL in %s:%d\n",f,l);
145    return FALSE;
146  }
147  //if ((int)a==1) Print("!! 0x1 as number ? %s %d\n",f,l);
148  if ((((long)a)&3L)==3L)
149  {
150    Print(" !!longrat:ptr(3) in %s:%d\n",f,l);
151    return FALSE;
152  }
153  if ((((long)a)&3L)==1L)
154  {
155    if (((((long)a)<<1)>>1)!=((long)a))
156    {
157      Print(" !!longrat:arith:%x in %s:%d\n",(long)a, f,l);
158      return FALSE;
159    }
160    return TRUE;
161  }
162  omCheckIf(omCheckAddrSize(a,sizeof(*a)), return FALSE);
163  if (a->debug!=123456)
164  {
165    Print("!!longrat:debug:%d in %s:%d\n",a->debug,f,l);
166    a->debug=123456;
167    return FALSE;
168  }
169  if ((a->s<0)||(a->s>4))
170  {
171    Print("!!longrat:s=%d in %s:%d\n",a->s,f,l);
172    return FALSE;
173  }
174  omCheckAddrSize(a->z._mp_d,a->z._mp_alloc*BYTES_PER_MP_LIMB);
175  if (a->z._mp_alloc==0)
176    Print("!!longrat:z->alloc=0 in %s:%l\n",f,l);
177
178  if (a->s<2)
179  {
180    omCheckIf(omCheckAddrSize(a->n._mp_d,a->n._mp_alloc*BYTES_PER_MP_LIMB), return FALSE);
181    if (a->z._mp_alloc==0)
182      Print("!!longrat:n->alloc=0 in %s:%l\n",f,l);
183    if ((mpz_size1(&a->n) ==1) && (mpz_cmp_si(&a->n,(long)1)==0))
184    {
185      Print("!!longrat:integer as rational in %s:%d\n",f,l);
186      return FALSE;
187    }
188    else if (mpz_isNeg(&a->n))
189    {
190      Print("!!longrat:div. by negative in %s:%d\n",f,l);
191      mpz_neg(&a->z,&a->z);
192      mpz_neg(&a->n,&a->n);
193      return FALSE;
194    }
195    return TRUE;
196  }
197  if (a->s==2)
198  {
199    Print("!!longrat:s=2 in %s:%d\n",f,l);
200    return FALSE;
201  }
202  if (mpz_size1(&a->z)>MP_SMALL) return TRUE;
203  int ui=(int)mpz_get_si(&a->z);
204  if ((((ui<<3)>>3)==ui)
205  && (mpz_cmp_si(&a->z,(long)ui)==0))
206  {
207    Print("!!longrat:im int %d in %s:%d\n",ui,f,l);
208    f=NULL;
209    return FALSE;
210  }
211  return TRUE;
212}
213#endif
214
215number nlRInit (int i);
216
217static number nlMapR(number from)
218{
219  double f=nrFloat(from);
220  if (f==0.0) return INT_TO_SR(0);
221  int f_sign=1;
222  if (f<0.0)
223  {
224    f_sign=-1;
225    f=-f;
226  }
227  int i=0;
228  mpz_t h1;
229  mpz_init_set_ui(h1,1);
230  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
231  {
232    f*=FLT_RADIX;
233    mpz_mul_ui(h1,h1,FLT_RADIX);
234    i++;
235  }
236  number r=nlRInit(1);
237  mpz_set_d(&(r->z),f);
238  memcpy4(&(r->n),&h1,sizeof(h1));
239  r->s=0; /* not normalized */
240  nlNormalize(r);
241  return r;
242}
243
244static number nlMapLongR(number from)
245{
246  gmp_float *ff=(gmp_float*)from;
247  mpf_t *f=ff->_mpfp();
248  number res;
249  lint *dest,*ndest;
250  int size, i,negative;
251  int e,al,bl;
252  mp_ptr qp,dd,nn;
253
254  size = (*f)[0]._mp_size;
255  if (size == 0)
256    return INT_TO_SR(0);
257  if(size<0)
258  {
259    negative = 1;
260    size = -size;
261  }
262  else
263    negative = 0;
264
265  qp = (*f)[0]._mp_d;
266  while(qp[0]==0)
267  {
268    qp++;
269    size--;
270  }
271
272  e=(*f)[0]._mp_exp-size;
273  res = (number)omAllocBin(rnumber_bin);
274#if defined(LDEBUG)
275  res->debug=123456;
276#endif
277  dest = &(res->z);
278
279  if (e<0)
280  {
281    al = dest->_mp_size = size;
282    if (al<2) al = 2;
283    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
284    for (i=0;i<size;i++) dd[i] = qp[i];
285    bl = 1-e;
286    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
287    nn[bl-1] = 1;
288    for (i=bl-2;i>=0;i--) nn[i] = 0;
289    ndest = &(res->n);
290    ndest->_mp_d = nn;
291    ndest->_mp_alloc = ndest->_mp_size = bl;
292    res->s = 0;
293  }
294  else
295  {
296    al = dest->_mp_size = size+e;
297    if (al<2) al = 2;
298    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
299    for (i=0;i<size;i++) dd[i+e] = qp[i];
300    for (i=0;i<e;i++) dd[i] = 0;
301    res->s = 3;
302  }
303
304  dest->_mp_d = dd;
305  dest->_mp_alloc = al;
306  if (negative) dest->_mp_size = -dest->_mp_size;
307
308  if (res->s==0)
309    nlNormalize(res);
310  else if (mpz_size1(&res->z)<=MP_SMALL)
311  {
312    // res is new, res->ref is 1
313    int ui=(int)mpz_get_si(&res->z);
314    if ((((ui<<3)>>3)==ui)
315       && (mpz_cmp_si(&res->z,(long)ui)==0))
316    {
317       mpz_clear(&res->z);
318#if defined(LDEBUG)
319       res->debug=654324;
320#endif
321       omFreeBin((ADDRESS)res, rnumber_bin);
322       return INT_TO_SR(ui);
323    }
324  }
325#if defined(LDEBUG)
326  nlTest(res);
327#endif
328  return res;
329}
330
331//static number nlMapLongR(number from)
332//{
333//  gmp_float *ff=(gmp_float*)from;
334//  const mpf_t *f=ff->mpfp();
335//  int f_size=ABS((*f)[0]._mp_size);
336//  if (f_size==0)
337//    return nlInit(0);
338//  int f_sign=1;
339//  number work=ngcCopy(from);
340//  if (!ngcGreaterZero(work))
341//  {
342//    f_sign=-1;
343//    work=ngcNeg(work);
344//  }
345//  int i=0;
346//  mpz_t h1;
347//  mpz_init_set_ui(h1,1);
348//  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
349//  {
350//    f*=FLT_RADIX;
351//    mpz_mul_ui(h1,h1,FLT_RADIX);
352//    i++;
353//  }
354//  number r=nlRInit(1);
355//  mpz_set_d(&(r->z),f);
356//  memcpy4(&(r->n),&h1,sizeof(h1));
357//  r->s=0; /* not normalized */
358//  nlNormalize(r);
359//  return r;
360//
361//
362//  number r=nlRInit(1);
363//  int f_shift=f_size+(*f)[0]._mp_exp;
364//  if ( f_shift > 0)
365//  {
366//    r->s=0;
367//    mpz_init(&r->n);
368//    mpz_setbit(&r->n,f_shift*BYTES_PER_MP_LIMB*8);
369//    mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
370//    // now r->z has enough space
371//    memcpy4(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
372//    nlNormalize(r);
373//  }
374//  else
375//  {
376//    r->s=3;
377//    if (f_shift==0)
378//    {
379//      mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
380//      // now r->z has enough space
381//      memcpy4(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
382//    }
383//    else /* f_shift < 0 */
384//    {
385//      mpz_setbit(&r->z,(f_size-f_shift)*BYTES_PER_MP_LIMB*8-1);
386//      // now r->z has enough space
387//      memcpy4(mpz_limb_d(&r->z)-f_shift,((*f)[0]._mp_d),
388//        f_size*BYTES_PER_MP_LIMB);
389//    }
390//  }
391//  if ((*f)[0]._mp_size<0);
392//    r=nlNeg(r);
393//  return r;
394//}
395
396int nlSize(number a)
397{
398  if (a==INT_TO_SR(0))
399     return 0; /* rational 0*/
400  if (SR_HDL(a) & SR_INT)
401     return 1; /* immidiate int */
402  int s=a->z._mp_alloc;
403//  while ((s>0) &&(a->z._mp_d[s]==0L)) s--;
404//#if SIZEOF_LONG == 8
405//  if (a->z._mp_d[s] < (unsigned long)0x100000000L) s=s*2-1;
406//  else s *=2;
407//#endif
408//  s++;
409  if (a->s<2)
410  {
411    int d=a->n._mp_alloc;
412//    while ((d>0) && (a->n._mp_d[d]==0L)) d--;
413//#if SIZEOF_LONG == 8
414//    if (a->n._mp_d[d] < (unsigned long)0x100000000L) d=d*2-1;
415//    else d *=2;
416//#endif
417    s+=d;
418  }
419  return s;
420}
421
422/*2
423* convert number to int
424*/
425int nlInt(number &i)
426{
427#ifdef LDEBUG
428  nlTest(i);
429#endif
430  nlNormalize(i);
431  if (SR_HDL(i) &SR_INT) return SR_TO_INT(i);
432  if (i->s==3)
433  {
434    if(mpz_size1(&i->z)>MP_SMALL) return 0;
435    int ul=(int)mpz_get_si(&i->z);
436    if (mpz_cmp_si(&i->z,(long)ul)!=0) return 0;
437    return ul;
438  }
439  lint tmp;
440  int ul;
441  mpz_init(&tmp);
442  MPZ_DIV(&tmp,&i->z,&i->n);
443  if(mpz_size1(&tmp)>MP_SMALL) ul=0;
444  else
445  {
446    ul=(int)mpz_get_si(&tmp);
447    if (mpz_cmp_si(&tmp,(long)ul)!=0) ul=0;
448  }
449  mpz_clear(&tmp);
450  return ul;
451}
452
453/*2
454* convert number to bigint
455*/
456number nlBigInt(number &i)
457{
458#ifdef LDEBUG
459  nlTest(i);
460#endif
461  nlNormalize(i);
462  if (SR_HDL(i) &SR_INT) return (i);
463  if (i->s==3)
464  {
465    return nlCopy(i);
466  }
467  number tmp=nlRInit(1);
468  MPZ_DIV(&tmp->z,&i->z,&i->n);
469  nlNormalize(tmp);
470  return tmp;
471}
472
473/*
474* 1/a
475*/
476number nlInvers(number a)
477{
478#ifdef LDEBUG
479  nlTest(a);
480#endif
481  number n;
482  if (SR_HDL(a) & SR_INT)
483  {
484    if ((a==INT_TO_SR(1)) || (a==INT_TO_SR(-1)))
485    {
486      return a;
487    }
488    if (nlIsZero(a))
489    {
490      WerrorS(nDivBy0);
491      return INT_TO_SR(0);
492    }
493    n=(number)omAllocBin(rnumber_bin);
494#if defined(LDEBUG)
495    n->debug=123456;
496#endif
497    n->s=1;
498    if ((long)a>0L)
499    {
500      mpz_init_set_si(&n->z,(long)1);
501      mpz_init_set_si(&n->n,(long)SR_TO_INT(a));
502    }
503    else
504    {
505      mpz_init_set_si(&n->z,(long)-1);
506      mpz_init_set_si(&n->n,(long)-SR_TO_INT(a));
507    }
508#ifdef LDEBUG
509    nlTest(n);
510#endif
511    return n;
512  }
513  n=(number)omAllocBin(rnumber_bin);
514#if defined(LDEBUG)
515  n->debug=123456;
516#endif
517  {
518    n->s=a->s;
519    mpz_init_set(&n->n,&a->z);
520    switch (a->s)
521    {
522      case 0:
523      case 1:
524              mpz_init_set(&n->z,&a->n);
525              if (mpz_isNeg(&n->n)) /* && n->s<2*/
526              {
527                mpz_neg(&n->z,&n->z);
528                mpz_neg(&n->n,&n->n);
529              }
530              if (mpz_cmp_si(&n->n,(long)1)==0)
531              {
532                mpz_clear(&n->n);
533                n->s=3;
534                if (mpz_size1(&n->z)<=MP_SMALL)
535                {
536                  int ui=(int)mpz_get_si(&n->z);
537                  if ((((ui<<3)>>3)==ui)
538                  && (mpz_cmp_si(&n->z,(long)ui)==0))
539                  {
540                    mpz_clear(&n->z);
541#if defined(LDEBUG)
542                    n->debug=654324;
543#endif
544                    omFreeBin((ADDRESS)n, rnumber_bin);
545                    n=INT_TO_SR(ui);
546                  }
547                }
548              }
549              break;
550      case 3:
551              n->s=1;
552              if (mpz_isNeg(&n->n)) /* && n->s<2*/
553              {
554                mpz_neg(&n->n,&n->n);
555                mpz_init_set_si(&n->z,(long)-1);
556              }
557              else
558              {
559                mpz_init_set_si(&n->z,(long)1);
560              }
561              break;
562    }
563  }
564#ifdef LDEBUG
565  nlTest(n);
566#endif
567  return n;
568}
569
570
571/*2
572* u := a / b in Z, if b | a (else undefined)
573*/
574number   nlExactDiv(number a, number b)
575{
576  if (b==INT_TO_SR(0))
577  {
578    WerrorS(nDivBy0);
579    return INT_TO_SR(0);
580  }
581  if (a==INT_TO_SR(0))
582    return INT_TO_SR(0);
583  number u;
584  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
585  {
586    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
587    if ((a==INT_TO_SR(-(1<<28)))&&(b==INT_TO_SR(-1)))
588    {
589      return nlRInit(1<<28);
590    }
591    int aa=SR_TO_INT(a);
592    int bb=SR_TO_INT(b);
593    return INT_TO_SR(aa/bb);
594  }
595  number bb=NULL;
596  if (SR_HDL(b) & SR_INT)
597  {
598    bb=nlRInit(SR_TO_INT(b));
599    b=bb;
600  }
601  u=(number)omAllocBin(rnumber_bin);
602#if defined(LDEBUG)
603  u->debug=123456;
604#endif
605  mpz_init(&u->z);
606  /* u=a/b */
607  u->s = 3;
608  MPZ_EXACTDIV(&u->z,&a->z,&b->z);
609  if (bb!=NULL)
610  {
611    mpz_clear(&bb->z);
612#if defined(LDEBUG)
613    bb->debug=654324;
614#endif
615    omFreeBin((ADDRESS)bb, rnumber_bin);
616  }
617  if (mpz_size1(&u->z)<=MP_SMALL)
618  {
619    int ui=(int)mpz_get_si(&u->z);
620    if ((((ui<<3)>>3)==ui)
621    && (mpz_cmp_si(&u->z,(long)ui)==0))
622    {
623      mpz_clear(&u->z);
624#if defined(LDEBUG)
625      u->debug=654324;
626#endif
627      omFreeBin((ADDRESS)u, rnumber_bin);
628      u=INT_TO_SR(ui);
629    }
630  }
631#ifdef LDEBUG
632  nlTest(u);
633#endif
634  return u;
635}
636
637/*2
638* u := a / b in Z
639*/
640number nlIntDiv (number a, number b)
641{
642  if (b==INT_TO_SR(0))
643  {
644    WerrorS(nDivBy0);
645    return INT_TO_SR(0);
646  }
647  if (a==INT_TO_SR(0))
648    return INT_TO_SR(0);
649  number u;
650  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
651  {
652    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
653    if ((a==INT_TO_SR(-(1<<28)))&&(b==INT_TO_SR(-1)))
654    {
655      return nlRInit(1<<28);
656    }
657    int aa=SR_TO_INT(a);
658    int bb=SR_TO_INT(b);
659    return INT_TO_SR(aa/bb);
660  }
661  if (SR_HDL(a) & SR_INT)
662  {
663    /* the small int -(1<<28) divided by 2^28 is 1   */
664    if (a==INT_TO_SR(-(1<<28)))
665    {
666      if(mpz_cmp_si(&b->z,(long)(1<<28))==0)
667      {
668        return INT_TO_SR(-1);
669      }
670    }
671    /* a is a small and b is a large int: -> 0 */
672    return INT_TO_SR(0);
673  }
674  number bb=NULL;
675  if (SR_HDL(b) & SR_INT)
676  {
677    bb=nlRInit(SR_TO_INT(b));
678    b=bb;
679  }
680  u=(number)omAllocBin(rnumber_bin);
681#if defined(LDEBUG)
682  u->debug=123456;
683#endif
684  assume(a->s==3);
685  assume(b->s==3);
686  mpz_init_set(&u->z,&a->z);
687  /* u=u/b */
688  u->s = 3;
689  MPZ_DIV(&u->z,&u->z,&b->z);
690  if (bb!=NULL)
691  {
692    mpz_clear(&bb->z);
693#if defined(LDEBUG)
694    bb->debug=654324;
695#endif
696    omFreeBin((ADDRESS)bb, rnumber_bin);
697  }
698  if (mpz_size1(&u->z)<=MP_SMALL)
699  {
700    int ui=(int)mpz_get_si(&u->z);
701    if ((((ui<<3)>>3)==ui)
702    && (mpz_cmp_si(&u->z,(long)ui)==0))
703    {
704      mpz_clear(&u->z);
705#if defined(LDEBUG)
706      u->debug=654324;
707#endif
708      omFreeBin((ADDRESS)u, rnumber_bin);
709      u=INT_TO_SR(ui);
710    }
711  }
712#ifdef LDEBUG
713  nlTest(u);
714#endif
715  return u;
716}
717
718/*2
719* u := a mod b in Z, u>=0
720*/
721number nlIntMod (number a, number b)
722{
723  if (b==INT_TO_SR(0))
724  {
725    WerrorS(nDivBy0);
726    return INT_TO_SR(0);
727  }
728  if (a==INT_TO_SR(0))
729    return INT_TO_SR(0);
730  number u;
731  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
732  {
733    if ((long)a>0L)
734    {
735      if ((long)b>0L)
736        return INT_TO_SR(SR_TO_INT(a)%SR_TO_INT(b));
737      else
738        return INT_TO_SR(SR_TO_INT(a)%(-SR_TO_INT(b)));
739    }
740    else
741    {
742      if ((long)b>0L)
743      {
744        int i=(-SR_TO_INT(a))%SR_TO_INT(b);
745        if ( i != 0 ) i = (SR_TO_INT(b))-i;
746        return INT_TO_SR(i);
747      }
748      else
749      {
750        int i=(-SR_TO_INT(a))%(-SR_TO_INT(b));
751        if ( i != 0 ) i = (-SR_TO_INT(b))-i;
752        return INT_TO_SR(i);
753      }
754    }
755  }
756  if (SR_HDL(a) & SR_INT)
757  {
758    /* a is a small and b is a large int: -> a or (a+b) or (a-b) */
759    if ((long)a<0L)
760    {
761      if (mpz_isNeg(&b->z))
762        return nlSub(a,b);
763      /*else*/
764        return nlAdd(a,b);
765    }
766    /*else*/
767      return a;
768  }
769  number bb=NULL;
770  if (SR_HDL(b) & SR_INT)
771  {
772    bb=nlRInit(SR_TO_INT(b));
773    b=bb;
774  }
775  u=(number)omAllocBin(rnumber_bin);
776#if defined(LDEBUG)
777  u->debug=123456;
778#endif
779  mpz_init(&u->z);
780  u->s = 3;
781  mpz_mod(&u->z,&a->z,&b->z);
782  if (bb!=NULL)
783  {
784    mpz_clear(&bb->z);
785#if defined(LDEBUG)
786    bb->debug=654324;
787#endif
788    omFreeBin((ADDRESS)bb, rnumber_bin);
789  }
790  if (mpz_isNeg(&u->z))
791  {
792    if (mpz_isNeg(&b->z))
793      mpz_sub(&u->z,&u->z,&b->z);
794    else
795      mpz_add(&u->z,&u->z,&b->z);
796  }
797  if (mpz_size1(&u->z)<=MP_SMALL)
798  {
799    int ui=(int)mpz_get_si(&u->z);
800    if ((((ui<<3)>>3)==ui)
801    && (mpz_cmp_si(&u->z,(long)ui)==0))
802    {
803      mpz_clear(&u->z);
804#if defined(LDEBUG)
805      u->debug=654324;
806#endif
807      omFreeBin((ADDRESS)u, rnumber_bin);
808      u=INT_TO_SR(ui);
809    }
810  }
811#ifdef LDEBUG
812  nlTest(u);
813#endif
814  return u;
815}
816
817/*2
818* u := a / b
819*/
820number nlDiv (number a, number b)
821{
822  number u;
823  if (nlIsZero(b))
824  {
825    WerrorS(nDivBy0);
826    return INT_TO_SR(0);
827  }
828  u=(number)omAllocBin(rnumber_bin);
829  u->s=0;
830#if defined(LDEBUG)
831  u->debug=123456;
832#endif
833// ---------- short / short ------------------------------------
834  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
835  {
836    int i=SR_TO_INT(a);
837    int j=SR_TO_INT(b);
838    int r=i%j;
839    if (r==0)
840    {
841      omFreeBin((ADDRESS)u, rnumber_bin);
842      return INT_TO_SR(i/j);
843    }
844    mpz_init_set_si(&u->z,(long)i);
845    mpz_init_set_si(&u->n,(long)j);
846  }
847  else
848  {
849    mpz_init(&u->z);
850// ---------- short / long ------------------------------------
851    if (SR_HDL(a) & SR_INT)
852    {
853      // short a / (z/n) -> (a*n)/z
854      if (b->s<2)
855      {
856        mpz_mul_si(&u->z,&b->n,SR_TO_INT(a));
857      }
858      else
859      // short a / long z -> a/z
860      {
861        mpz_set_si(&u->z,SR_TO_INT(a));
862      }
863      if (mpz_cmp(&u->z,&b->z)==0)
864      {
865        mpz_clear(&u->z);
866        omFreeBin((ADDRESS)u, rnumber_bin);
867        return INT_TO_SR(1);
868      }
869      mpz_init_set(&u->n,&b->z);
870    }
871// ---------- long / short ------------------------------------
872    else if (SR_HDL(b) & SR_INT)
873    {
874      mpz_set(&u->z,&a->z);
875      // (z/n) / b -> z/(n*b)
876      if (a->s<2)
877      {
878        mpz_init_set(&u->n,&a->n);
879        if ((long)b>0L)
880          mpz_mul_ui(&u->n,&u->n,SR_TO_INT(b));
881        else
882        {
883          mpz_mul_ui(&u->n,&u->n,-SR_TO_INT(b));
884          mpz_neg(&u->z,&u->z);
885        }
886      }
887      else
888      // long z / short b -> z/b
889      {
890        //mpz_set(&u->z,&a->z);
891        mpz_init_set_si(&u->n,SR_TO_INT(b));
892      }
893    }
894// ---------- long / long ------------------------------------
895    else
896    {
897      mpz_set(&u->z,&a->z);
898      mpz_init_set(&u->n,&b->z);
899      if (a->s<2) mpz_mul(&u->n,&u->n,&a->n);
900      if (b->s<2) mpz_mul(&u->z,&u->z,&b->n);
901    }
902  }
903  if (mpz_isNeg(&u->n))
904  {
905    mpz_neg(&u->z,&u->z);
906    mpz_neg(&u->n,&u->n);
907  }
908  if (mpz_cmp_si(&u->n,(long)1)==0)
909  {
910    mpz_clear(&u->n);
911    if (mpz_size1(&u->z)<=MP_SMALL)
912    {
913      int ui=(int)mpz_get_si(&u->z);
914      if ((((ui<<3)>>3)==ui)
915      && (mpz_cmp_si(&u->z,(long)ui)==0))
916      {
917        mpz_clear(&u->z);
918        omFreeBin((ADDRESS)u, rnumber_bin);
919        return INT_TO_SR(ui);
920      }
921    }
922    u->s=3;
923  }
924#ifdef LDEBUG
925  nlTest(u);
926#endif
927  return u;
928}
929
930/*2
931* u:= x ^ exp
932*/
933void nlPower (number x,int exp,number * u)
934{
935  *u = INT_TO_SR(0); // 0^e, e!=0
936  if (!nlIsZero(x))
937  {
938#ifdef LDEBUG
939    nlTest(x);
940#endif
941    number aa=NULL;
942    if (SR_HDL(x) & SR_INT)
943    {
944      aa=nlRInit(SR_TO_INT(x));
945      x=aa;
946    }
947    else if (x->s==0)
948      nlNormalize(x);
949    *u=(number)omAllocBin(rnumber_bin);
950#if defined(LDEBUG)
951    (*u)->debug=123456;
952#endif
953    mpz_init(&(*u)->z);
954    mpz_pow_ui(&(*u)->z,&x->z,(unsigned long)exp);
955    if (x->s<2)
956    {
957      if (mpz_cmp_si(&x->n,(long)1)==0)
958      {
959        x->s=3;
960        mpz_clear(&x->n);
961      }
962      else
963      {
964        mpz_init(&(*u)->n);
965        mpz_pow_ui(&(*u)->n,&x->n,(unsigned long)exp);
966      }
967    }
968    (*u)->s = x->s;
969    if (((*u)->s==3) && (mpz_size1(&(*u)->z)<=MP_SMALL))
970    {
971      int ui=(int)mpz_get_si(&(*u)->z);
972      if ((((ui<<3)>>3)==ui)
973      && (mpz_cmp_si(&(*u)->z,(long)ui)==0))
974      {
975        mpz_clear(&(*u)->z);
976        omFreeBin((ADDRESS)*u, rnumber_bin);
977        *u=INT_TO_SR(ui);
978      }
979    }
980    if (aa!=NULL)
981    {
982      mpz_clear(&aa->z);
983      omFreeBin((ADDRESS)aa, rnumber_bin);
984    }
985  }
986  else if (exp==0)
987    *u = INT_TO_SR(1); // 0^0
988#ifdef LDEBUG
989  nlTest(*u);
990#endif
991}
992
993
994/*2
995* za >= 0 ?
996*/
997BOOLEAN nlGreaterZero (number a)
998{
999#ifdef LDEBUG
1000  nlTest(a);
1001#endif
1002  if (SR_HDL(a) & SR_INT) return SR_HDL(a)>1 /* represents number(0) */;
1003  return (!mpz_isNeg(&a->z));
1004}
1005
1006/*2
1007* a > b ?
1008*/
1009BOOLEAN nlGreater (number a, number b)
1010{
1011#ifdef LDEBUG
1012  nlTest(a);
1013  nlTest(b);
1014#endif
1015  number r;
1016  BOOLEAN rr;
1017  r=nlSub(a,b);
1018  rr=(!nlIsZero(r)) && (nlGreaterZero(r));
1019  nlDelete(&r,currRing);
1020  return rr;
1021}
1022
1023/*2
1024* a == -1 ?
1025*/
1026BOOLEAN nlIsMOne (number a)
1027{
1028#ifdef LDEBUG
1029  if (a==NULL) return FALSE;
1030  nlTest(a);
1031#endif
1032  if (SR_HDL(a) & SR_INT) return (a==INT_TO_SR(-1));
1033  return FALSE;
1034}
1035
1036/*2
1037* result =gcd(a,b)
1038*/
1039number nlGcd(number a, number b, const ring r)
1040{
1041  number result;
1042#ifdef LDEBUG
1043  nlTest(a);
1044  nlTest(b);
1045#endif
1046  //nlNormalize(a);
1047  //nlNormalize(b);
1048  if ((a==INT_TO_SR(1))||(a==INT_TO_SR(-1))
1049  ||  (b==INT_TO_SR(1))||(b==INT_TO_SR(-1)))
1050    return INT_TO_SR(1);
1051  if (a==INT_TO_SR(0)) /* gcd(0,b) ->b */
1052    return nlCopy(b);
1053  if (b==INT_TO_SR(0)) /* gcd(a,0) -> a */
1054    return nlCopy(a);
1055  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
1056  {
1057    int i=SR_TO_INT(a);
1058    int j=SR_TO_INT(b);
1059    if((i==0)||(j==0))
1060      return INT_TO_SR(1);
1061    int l;
1062    i=ABS(i);
1063    j=ABS(j);
1064    do
1065    {
1066      l=i%j;
1067      i=j;
1068      j=l;
1069    } while (l!=0);
1070    return INT_TO_SR(i);
1071  }
1072  if (((!(SR_HDL(a) & SR_INT))&&(a->s<2))
1073  ||  ((!(SR_HDL(b) & SR_INT))&&(b->s<2))) return INT_TO_SR(1);
1074  result=(number)omAllocBin(rnumber_bin);
1075#if defined(LDEBUG)
1076  result->debug=123456;
1077#endif
1078  mpz_init(&result->z);
1079  if (SR_HDL(a) & SR_INT)
1080  {
1081    unsigned long t=mpz_gcd_ui(NULL,&b->z,ABS(SR_TO_INT(a)));
1082    return INT_TO_SR((int)t);
1083  }
1084  else
1085  if (SR_HDL(b) & SR_INT)
1086  {
1087    unsigned long t=mpz_gcd_ui(NULL,&a->z,ABS(SR_TO_INT(b)));
1088    return INT_TO_SR((int)t);
1089  }
1090  else
1091  {
1092    mpz_gcd(&result->z,&a->z,&b->z);
1093  }
1094  result->s = 3;
1095  if (mpz_size1(&result->z)<=MP_SMALL)
1096  {
1097    int ui=(int)mpz_get_si(&result->z);
1098    if ((((ui<<3)>>3)==ui)
1099    && (mpz_cmp_si(&result->z,(long)ui)==0))
1100    {
1101      mpz_clear(&result->z);
1102      omFreeBin((ADDRESS)result, rnumber_bin);
1103      result=INT_TO_SR(ui);
1104    }
1105  }
1106#ifdef LDEBUG
1107  nlTest(result);
1108#endif
1109  return result;
1110}
1111
1112/*2
1113* simplify x
1114*/
1115void nlNormalize (number &x)
1116{
1117  if ((SR_HDL(x) & SR_INT) ||(x==NULL))
1118    return;
1119#ifdef LDEBUG
1120  if (!nlTest(x)) { x->s=1; return; }
1121#endif
1122  if (x->s==3)
1123  {
1124    if (mpz_cmp_ui(&x->z,(long)0)==0)
1125    {
1126      nlDelete(&x,currRing);
1127      x=INT_TO_SR(0);
1128      return;
1129    }
1130    if (mpz_size1(&x->z)<=MP_SMALL)
1131    {
1132      int ui=(int)mpz_get_si(&x->z);
1133      if ((((ui<<3)>>3)==ui)
1134      && (mpz_cmp_si(&x->z,(long)ui)==0))
1135      {
1136        mpz_clear(&x->z);
1137        omFreeBin((ADDRESS)x, rnumber_bin);
1138        x=INT_TO_SR(ui);
1139        return;
1140      }
1141    }
1142  }
1143  else if (x->s==0)
1144  {
1145    if (mpz_cmp_si(&x->n,(long)1)==0)
1146    {
1147      mpz_clear(&x->n);
1148      if (mpz_size1(&x->z)<=MP_SMALL)
1149      {
1150        int ui=(int)mpz_get_si(&x->z);
1151        if ((((ui<<3)>>3)==ui)
1152        && (mpz_cmp_si(&x->z,(long)ui)==0))
1153        {
1154          mpz_clear(&x->z);
1155#if defined(LDEBUG)
1156          x->debug=654324;
1157#endif
1158          omFreeBin((ADDRESS)x, rnumber_bin);
1159          x=INT_TO_SR(ui);
1160          return;
1161        }
1162      }
1163      x->s=3;
1164    }
1165    else
1166    {
1167      MP_INT gcd;
1168      mpz_init(&gcd);
1169      mpz_gcd(&gcd,&x->z,&x->n);
1170      x->s=1;
1171      if (mpz_cmp_si(&gcd,(long)1)!=0)
1172      {
1173        MP_INT r;
1174        mpz_init(&r);
1175        MPZ_EXACTDIV(&r,&x->z,&gcd);
1176        mpz_set(&x->z,&r);
1177        MPZ_EXACTDIV(&r,&x->n,&gcd);
1178        mpz_set(&x->n,&r);
1179        mpz_clear(&r);
1180        mpz_clear(&gcd);
1181        if (mpz_cmp_si(&x->n,(long)1)==0)
1182        {
1183          mpz_clear(&x->n);
1184          if (mpz_size1(&x->z)<=MP_SMALL)
1185          {
1186            int ui=(int)mpz_get_si(&x->z);
1187            if ((((ui<<3)>>3)==ui)
1188            && (mpz_cmp_si(&x->z,(long)ui)==0))
1189            {
1190              mpz_clear(&x->z);
1191#if defined(LDEBUG)
1192              x->debug=654324;
1193#endif
1194              omFreeBin((ADDRESS)x, rnumber_bin);
1195              x=INT_TO_SR(ui);
1196              return;
1197            }
1198          }
1199          x->s=3;
1200        }
1201      }
1202    }
1203  }
1204#ifdef LDEBUG
1205  nlTest(x);
1206#endif
1207}
1208
1209/*2
1210* returns in result->z the lcm(a->z,b->n)
1211*/
1212number nlLcm(number a, number b, const ring r)
1213{
1214  number result;
1215#ifdef LDEBUG
1216  nlTest(a);
1217  nlTest(b);
1218#endif
1219  if ((SR_HDL(b) & SR_INT)
1220  || (b->s==3))
1221  {
1222    // b is 1/(b->n) => b->n is 1 => result is a
1223    return nlCopy(a);
1224  }
1225  result=(number)omAllocBin(rnumber_bin);
1226#if defined(LDEBUG)
1227  result->debug=123456;
1228#endif
1229  result->s=3;
1230  MP_INT gcd;
1231  mpz_init(&gcd);
1232  mpz_init(&result->z);
1233  if (SR_HDL(a) & SR_INT)
1234    mpz_gcd_ui(&gcd,&b->n,ABS(SR_TO_INT(a)));
1235  else
1236    mpz_gcd(&gcd,&a->z,&b->n);
1237  if (mpz_cmp_si(&gcd,(long)1)!=0)
1238  {
1239    MP_INT bt;
1240    mpz_init_set(&bt,&b->n);
1241    MPZ_EXACTDIV(&bt,&bt,&gcd);
1242    if (SR_HDL(a) & SR_INT)
1243      mpz_mul_si(&result->z,&bt,SR_TO_INT(a));
1244    else
1245      mpz_mul(&result->z,&bt,&a->z);
1246    mpz_clear(&bt);
1247  }
1248  else
1249    if (SR_HDL(a) & SR_INT)
1250      mpz_mul_si(&result->z,&b->n,SR_TO_INT(a));
1251    else
1252      mpz_mul(&result->z,&b->n,&a->z);
1253  mpz_clear(&gcd);
1254  if (mpz_size1(&result->z)<=MP_SMALL)
1255  {
1256    int ui=(int)mpz_get_si(&result->z);
1257    if ((((ui<<3)>>3)==ui)
1258    && (mpz_cmp_si(&result->z,(long)ui)==0))
1259    {
1260      mpz_clear(&result->z);
1261      omFreeBin((ADDRESS)result, rnumber_bin);
1262      return INT_TO_SR(ui);
1263    }
1264  }
1265#ifdef LDEBUG
1266  nlTest(result);
1267#endif
1268  return result;
1269}
1270
1271int nlModP(number n, int p)
1272{
1273  if (SR_HDL(n) & SR_INT)
1274  {
1275    int i=SR_TO_INT(n);
1276    if (i<0) return (p-((-i)%p));
1277    return i%p;
1278  }
1279  int iz=(int)mpz_mmod_ui(NULL,&n->z,(unsigned long)p);
1280  if (n->s!=3)
1281  {
1282    int in=mpz_mmod_ui(NULL,&n->n,(unsigned long)p);
1283    #ifdef NV_OPS
1284    if (npPrimeM>NV_MAX_PRIME)
1285    return (int)((long)nvDiv((number)iz,(number)in));
1286    #endif
1287    return (int)((long)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 (((long)a > 0L) && (mpz_isNeg(&b->z)))
1387      return FALSE;
1388    if (((long)a < 0L) && (!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 ((long)a>0L)
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 ((long)a>0L)
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 ((long)b>0L)
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,(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 ((long)a>0L)
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
2100number nlInit2gmp (mpz_t i, mpz_t j)
2101{
2102  number z=(number)omAllocBin(rnumber_bin);
2103#if defined(LDEBUG)
2104  z->debug=123456;
2105#endif
2106  mpz_init_set(&z->z,i);
2107  mpz_init_set(&z->n,j);
2108  z->s = 0;
2109  nlNormalize(z);
2110  return z;
2111}
2112
2113#else // DO_LINLINE
2114
2115// declare immedate routines
2116number nlRInit (int i);
2117BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b);
2118number  _nlCopy_NoImm(number a);
2119void    _nlDelete_NoImm(number *a, const ring r);
2120number  _nlNeg_NoImm(number a);
2121number  _nlAdd_aNoImm_OR_bNoImm(number a, number b);
2122number  _nlSub_aNoImm_OR_bNoImm(number a, number b);
2123number  _nlMult_aNoImm_OR_bNoImm(number a, number b);
2124number  _nlMult_aImm_bImm_rNoImm(number a, number b);
2125
2126#endif
2127
2128
2129/***************************************************************
2130 *
2131 * Routines which might be inlined by p_Numbers.h
2132 *
2133 *******************************************************************/
2134#if defined(DO_LINLINE) || !defined(P_NUMBERS_H)
2135
2136// routines which are always inlined/static
2137
2138/*2
2139* a = b ?
2140*/
2141LINLINE BOOLEAN nlEqual (number a, number b)
2142{
2143#ifdef LDEBUG
2144  nlTest(a);
2145  nlTest(b);
2146#endif
2147// short - short
2148  if (SR_HDL(a) & SR_HDL(b) & SR_INT) return a==b;
2149  return _nlEqual_aNoImm_OR_bNoImm(a, b);
2150}
2151
2152
2153LINLINE number nlInit (int i)
2154{
2155  number n;
2156  if ( ((i << 3) >> 3) == i ) n=INT_TO_SR(i);
2157  else                        n=nlRInit(i);
2158#ifdef LDEBUG
2159  nlTest(n);
2160#endif
2161  return n;
2162}
2163
2164
2165/*2
2166* a == 1 ?
2167*/
2168LINLINE BOOLEAN nlIsOne (number a)
2169{
2170#ifdef LDEBUG
2171  if (a==NULL) return FALSE;
2172  nlTest(a);
2173#endif
2174  if (SR_HDL(a) & SR_INT) return (a==INT_TO_SR(1));
2175  return FALSE;
2176}
2177
2178LINLINE BOOLEAN nlIsZero (number a)
2179{
2180  return (a==INT_TO_SR(0));
2181}
2182
2183/*2
2184* copy a to b
2185*/
2186LINLINE number nlCopy(number a)
2187{
2188  if ((SR_HDL(a) & SR_INT)||(a==NULL))
2189  {
2190    return a;
2191  }
2192  return _nlCopy_NoImm(a);
2193}
2194
2195
2196LINLINE void nlNew (number * r)
2197{
2198  *r=NULL;
2199}
2200
2201/*2
2202* delete a
2203*/
2204LINLINE void nlDelete (number * a, const ring r)
2205{
2206  if (*a!=NULL)
2207  {
2208#ifdef LDEBUG
2209    nlTest(*a);
2210#endif
2211    if ((SR_HDL(*a) & SR_INT)==0)
2212    {
2213      _nlDelete_NoImm(a,r);
2214    }
2215    *a=NULL;
2216  }
2217}
2218
2219/*2
2220* za:= - za
2221*/
2222LINLINE number nlNeg (number a)
2223{
2224#ifdef LDEBUG
2225  nlTest(a);
2226#endif
2227  if(SR_HDL(a) &SR_INT)
2228  {
2229    int r=SR_TO_INT(a);
2230    if (r==(-(1<<28))) a=nlRInit(1<<28);
2231    else               a=INT_TO_SR(-r);
2232    return a;
2233  }
2234  return _nlNeg_NoImm(a);
2235}
2236
2237/*2
2238* u:= a + b
2239*/
2240LINLINE number nlAdd (number a, number b)
2241{
2242  number u;
2243  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2244  {
2245    int r=SR_HDL(a)+SR_HDL(b)-1;
2246    if ( ((r << 1) >> 1) == r )
2247      return (number)(long)r;
2248    else
2249      return nlRInit(SR_TO_INT(r));
2250  }
2251  return _nlAdd_aNoImm_OR_bNoImm(a, b);
2252}
2253
2254LINLINE number nlMult (number a, number b)
2255{
2256#ifdef LDEBUG
2257  nlTest(a);
2258  nlTest(b);
2259#endif
2260  if (a==INT_TO_SR(0)) return INT_TO_SR(0);
2261  if (b==INT_TO_SR(0)) return INT_TO_SR(0);
2262  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2263  {
2264    int r=(SR_HDL(a)-1)*(SR_HDL(b)>>1);
2265    if ((r/(SR_HDL(b)>>1))==(SR_HDL(a)-1))
2266    {
2267      number u=((number) ((r>>1)+SR_INT));
2268      if (((SR_HDL(u)<<1)>>1)==SR_HDL(u)) return (u);
2269      return nlRInit(SR_HDL(u)>>2);
2270    }
2271    return _nlMult_aImm_bImm_rNoImm(a, b);
2272  }
2273  return _nlMult_aNoImm_OR_bNoImm(a, b);
2274}
2275
2276
2277/*2
2278* u:= a - b
2279*/
2280LINLINE number nlSub (number a, number b)
2281{
2282  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2283  {
2284    int r=SR_HDL(a)-SR_HDL(b)+1;
2285    if ( ((r << 1) >> 1) == r )
2286    {
2287      return (number)r;
2288    }
2289    else
2290      return nlRInit(SR_TO_INT(r));
2291  }
2292  return _nlSub_aNoImm_OR_bNoImm(a, b);
2293}
2294
2295#endif // DO_LINLINE
2296
2297#ifndef P_NUMBERS_H
2298
2299void nlInpGcd(number &a, number b, ring r)
2300{
2301  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2302  {
2303    number n=nlGcd(a,b,r);
2304    nlDelete(&a,r);
2305    a=n;
2306  }
2307  else
2308  {
2309    mpz_gcd(&a->z,&a->z,&b->z);
2310    if (mpz_size1(&a->z)<=MP_SMALL)
2311    {
2312      int ui=(int)mpz_get_si(&a->z);
2313      if ((((ui<<3)>>3)==ui)
2314      && (mpz_cmp_si(&a->z,(long)ui)==0))
2315      {
2316        mpz_clear(&a->z);
2317        omFreeBin((ADDRESS)a, rnumber_bin);
2318        a=INT_TO_SR(ui);
2319      }
2320    }
2321  }
2322}
2323void nlInpIntDiv(number &a, number b, ring r)
2324{
2325  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2326  {
2327    number n=nlIntDiv(a,b);
2328    nlDelete(&a,r);
2329    a=n;
2330  }
2331  else
2332  {
2333    if (mpz_isNeg(&a->z))
2334    {
2335      if (mpz_isNeg(&b->z))
2336      {
2337        mpz_add(&a->z,&a->z,&b->z);
2338      }
2339      else
2340      {
2341        mpz_sub(&a->z,&a->z,&b->z);
2342      }
2343      mpz_add_ui(&a->z,&a->z,1);
2344    }
2345    else
2346    {
2347      if (mpz_isNeg(&b->z))
2348      {
2349        mpz_sub(&a->z,&a->z,&b->z);
2350      }
2351      else
2352      {
2353        mpz_add(&a->z,&a->z,&b->z);
2354      }
2355      mpz_sub_ui(&a->z,&a->z,1);
2356    }
2357    MPZ_DIV(&a->z,&a->z,&b->z);
2358    if (mpz_size1(&a->z)<=MP_SMALL)
2359    {
2360      int ui=(int)mpz_get_si(&a->z);
2361      if ((((ui<<3)>>3)==ui)
2362      && (mpz_cmp_si(&a->z,(long)ui)==0))
2363      {
2364        mpz_clear(&a->z);
2365        omFreeBin((ADDRESS)a, rnumber_bin);
2366        a=INT_TO_SR(ui);
2367      }
2368    }
2369  }
2370}
2371void nlInpAdd(number &a, number b, ring r)
2372{
2373  // TODO
2374  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2375  {
2376    number n=nlGcd(a,b,r);
2377    nlDelete(&a,r);
2378    a=n;
2379  }
2380  else
2381  {
2382    mpz_gcd(&a->z,&a->z,&b->z);
2383    if (mpz_size1(&a->z)<=MP_SMALL)
2384    {
2385      int ui=(int)mpz_get_si(&a->z);
2386      if ((((ui<<3)>>3)==ui)
2387      && (mpz_cmp_si(&a->z,(long)ui)==0))
2388      {
2389        mpz_clear(&a->z);
2390        omFreeBin((ADDRESS)a, rnumber_bin);
2391        a=INT_TO_SR(ui);
2392      }
2393    }
2394  }
2395}
2396void nlInpMult(number &a, number b, ring r)
2397{
2398  if (((SR_HDL(b)|SR_HDL(a))&SR_INT)
2399  )
2400  {
2401    number n=nlMult(a,b);
2402    nlDelete(&a,r);
2403    a=n;
2404  }
2405  else
2406  {
2407    mpz_mul(&a->z,&a->z,&b->z);
2408    if (a->s==3)
2409    {
2410      if(b->s!=3)
2411      {
2412        mpz_init_set(&a->n,&b->n);
2413        a->s=0;
2414      }
2415    }
2416    else
2417    {
2418      if(b->s!=3)
2419      {
2420        mpz_mul(&a->n,&a->n,&b->n);
2421      }
2422      a->s=0;
2423    }
2424  }
2425}
2426
2427#if 0
2428number nlMod(number a, number b)
2429{
2430  if (((SR_HDL(b)&SR_HDL(a))&SR_INT)
2431  {
2432    int bi=SR_TO_INT(b);
2433    int ai=SR_TO_INT(a);
2434    int bb=ABS(bi);
2435    int c=ai%bb;
2436    if (c<0)  c+=bb;
2437    return (INT_TO_SR(c));
2438  }
2439  number al;
2440  number bl;
2441  if (SR_HDL(a))&SR_INT)
2442    al=nlRInit(SR_TO_INT(a));
2443  else
2444    al=nlCopy(a);
2445  if (SR_HDL(b))&SR_INT)
2446    bl=nlRInit(SR_TO_INT(b));
2447  else
2448    bl=nlCopy(b);
2449  number r=nlRInit(0);
2450  mpz_mod(r->z,al->z,bl->z);
2451  nlDelete(&al);
2452  nlDelete(&bl);
2453  if (mpz_size1(&r->z)<=MP_SMALL)
2454  {
2455    int ui=(int)mpz_get_si(&r->z);
2456    if ((((ui<<3)>>3)==ui)
2457    && (mpz_cmp_si(&x->z,(long)ui)==0))
2458    {
2459      mpz_clear(&r->z);
2460      omFreeBin((ADDRESS)r, rnumber_bin);
2461      r=INT_TO_SR(ui);
2462    }
2463  }
2464  return r;
2465}
2466#endif
2467#endif // not P_NUMBERS_H
2468#endif // LONGRAT_CC
Note: See TracBrowser for help on using the repository browser.