source: git/kernel/longrat.cc @ 1c473f

spielwiese
Last change on this file since 1c473f was 7f7573, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: nlBigInt git-svn-id: file:///usr/local/Singular/svn/trunk@10586 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 50.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: longrat.cc,v 1.28 2008-02-20 13:58:34 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, char *f,int l)
141{
142  if (a==NULL)
143  {
144    Print("!!longrat: NULL in %s:%d\n",f,l);
145    return FALSE;
146  }
147  //if ((int)a==1) Print("!! 0x1 as number ? %s %d\n",f,l);
148  if ((((long)a)&3L)==3L)
149  {
150    Print(" !!longrat:ptr(3) in %s:%d\n",f,l);
151    return FALSE;
152  }
153  if ((((long)a)&3L)==1L)
154  {
155    if (((((long)a)<<1)>>1)!=((long)a))
156    {
157      Print(" !!longrat:arith:%x in %s:%d\n",(long)a, f,l);
158      return FALSE;
159    }
160    return TRUE;
161  }
162  omCheckIf(omCheckAddrSize(a,sizeof(*a)), return FALSE);
163  if (a->debug!=123456)
164  {
165    Print("!!longrat:debug:%d in %s:%d\n",a->debug,f,l);
166    a->debug=123456;
167    return FALSE;
168  }
169  if ((a->s<0)||(a->s>4))
170  {
171    Print("!!longrat:s=%d in %s:%d\n",a->s,f,l);
172    return FALSE;
173  }
174  omCheckAddrSize(a->z._mp_d,a->z._mp_alloc*BYTES_PER_MP_LIMB);
175  if (a->z._mp_alloc==0)
176    Print("!!longrat:z->alloc=0 in %s:%l\n",f,l);
177
178  if (a->s<2)
179  {
180    omCheckIf(omCheckAddrSize(a->n._mp_d,a->n._mp_alloc*BYTES_PER_MP_LIMB), return FALSE);
181    if (a->z._mp_alloc==0)
182      Print("!!longrat:n->alloc=0 in %s:%l\n",f,l);
183    if ((mpz_size1(&a->n) ==1) && (mpz_cmp_si(&a->n,(long)1)==0))
184    {
185      Print("!!longrat:integer as rational in %s:%d\n",f,l);
186      return FALSE;
187    }
188    else if (mpz_isNeg(&a->n))
189    {
190      Print("!!longrat:div. by negative in %s:%d\n",f,l);
191      mpz_neg(&a->z,&a->z);
192      mpz_neg(&a->n,&a->n);
193      return FALSE;
194    }
195    return TRUE;
196  }
197  if (a->s==2)
198  {
199    Print("!!longrat:s=2 in %s:%d\n",f,l);
200    return FALSE;
201  }
202  if (mpz_size1(&a->z)>MP_SMALL) return TRUE;
203  int ui=(int)mpz_get_si(&a->z);
204  if ((((ui<<3)>>3)==ui)
205  && (mpz_cmp_si(&a->z,(long)ui)==0))
206  {
207    Print("!!longrat:im int %d in %s:%d\n",ui,f,l);
208    f=NULL;
209    return FALSE;
210  }
211  return TRUE;
212}
213#endif
214
215number nlRInit (int i);
216
217static number nlMapR(number from)
218{
219  double f=nrFloat(from);
220  if (f==0.0) return INT_TO_SR(0);
221  int f_sign=1;
222  if (f<0.0)
223  {
224    f_sign=-1;
225    f=-f;
226  }
227  int i=0;
228  mpz_t h1;
229  mpz_init_set_ui(h1,1);
230  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
231  {
232    f*=FLT_RADIX;
233    mpz_mul_ui(h1,h1,FLT_RADIX);
234    i++;
235  }
236  number r=nlRInit(1);
237  mpz_set_d(&(r->z),f);
238  memcpy4(&(r->n),&h1,sizeof(h1));
239  r->s=0; /* not normalized */
240  nlNormalize(r);
241  return r;
242}
243
244static number nlMapLongR(number from)
245{
246  gmp_float *ff=(gmp_float*)from;
247  mpf_t *f=ff->_mpfp();
248  number res;
249  lint *dest,*ndest;
250  int size, i,negative;
251  int e,al,bl;
252  mp_ptr qp,dd,nn;
253
254  size = (*f)[0]._mp_size;
255  if (size == 0)
256    return INT_TO_SR(0);
257  if(size<0)
258  {
259    negative = 1;
260    size = -size;
261  }
262  else
263    negative = 0;
264
265  qp = (*f)[0]._mp_d;
266  while(qp[0]==0)
267  {
268    qp++;
269    size--;
270  }
271
272  e=(*f)[0]._mp_exp-size;
273  res = (number)omAllocBin(rnumber_bin);
274#if defined(LDEBUG)
275  res->debug=123456;
276#endif
277  dest = &(res->z);
278
279  if (e<0)
280  {
281    al = dest->_mp_size = size;
282    if (al<2) al = 2;
283    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
284    for (i=0;i<size;i++) dd[i] = qp[i];
285    bl = 1-e;
286    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
287    nn[bl-1] = 1;
288    for (i=bl-2;i>=0;i--) nn[i] = 0;
289    ndest = &(res->n);
290    ndest->_mp_d = nn;
291    ndest->_mp_alloc = ndest->_mp_size = bl;
292    res->s = 0;
293  }
294  else
295  {
296    al = dest->_mp_size = size+e;
297    if (al<2) al = 2;
298    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
299    for (i=0;i<size;i++) dd[i+e] = qp[i];
300    for (i=0;i<e;i++) dd[i] = 0;
301    res->s = 3;
302  }
303
304  dest->_mp_d = dd;
305  dest->_mp_alloc = al;
306  if (negative) dest->_mp_size = -dest->_mp_size;
307
308  if (res->s==0)
309    nlNormalize(res);
310  else if (mpz_size1(&res->z)<=MP_SMALL)
311  {
312    // res is new, res->ref is 1
313    int ui=(int)mpz_get_si(&res->z);
314    if ((((ui<<3)>>3)==ui)
315       && (mpz_cmp_si(&res->z,(long)ui)==0))
316    {
317       mpz_clear(&res->z);
318#if defined(LDEBUG)
319       res->debug=654324;
320#endif
321       omFreeBin((ADDRESS)res, rnumber_bin);
322       return INT_TO_SR(ui);
323    }
324  }
325#if defined(LDEBUG)
326  nlTest(res);
327#endif
328  return res;
329}
330
331//static number nlMapLongR(number from)
332//{
333//  gmp_float *ff=(gmp_float*)from;
334//  const mpf_t *f=ff->mpfp();
335//  int f_size=ABS((*f)[0]._mp_size);
336//  if (f_size==0)
337//    return nlInit(0);
338//  int f_sign=1;
339//  number work=ngcCopy(from);
340//  if (!ngcGreaterZero(work))
341//  {
342//    f_sign=-1;
343//    work=ngcNeg(work);
344//  }
345//  int i=0;
346//  mpz_t h1;
347//  mpz_init_set_ui(h1,1);
348//  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
349//  {
350//    f*=FLT_RADIX;
351//    mpz_mul_ui(h1,h1,FLT_RADIX);
352//    i++;
353//  }
354//  number r=nlRInit(1);
355//  mpz_set_d(&(r->z),f);
356//  memcpy4(&(r->n),&h1,sizeof(h1));
357//  r->s=0; /* not normalized */
358//  nlNormalize(r);
359//  return r;
360//
361//
362//  number r=nlRInit(1);
363//  int f_shift=f_size+(*f)[0]._mp_exp;
364//  if ( f_shift > 0)
365//  {
366//    r->s=0;
367//    mpz_init(&r->n);
368//    mpz_setbit(&r->n,f_shift*BYTES_PER_MP_LIMB*8);
369//    mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
370//    // now r->z has enough space
371//    memcpy4(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
372//    nlNormalize(r);
373//  }
374//  else
375//  {
376//    r->s=3;
377//    if (f_shift==0)
378//    {
379//      mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
380//      // now r->z has enough space
381//      memcpy4(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
382//    }
383//    else /* f_shift < 0 */
384//    {
385//      mpz_setbit(&r->z,(f_size-f_shift)*BYTES_PER_MP_LIMB*8-1);
386//      // now r->z has enough space
387//      memcpy4(mpz_limb_d(&r->z)-f_shift,((*f)[0]._mp_d),
388//        f_size*BYTES_PER_MP_LIMB);
389//    }
390//  }
391//  if ((*f)[0]._mp_size<0);
392//    r=nlNeg(r);
393//  return r;
394//}
395
396int nlSize(number a)
397{
398  if (a==INT_TO_SR(0))
399     return 0; /* rational 0*/
400  if (SR_HDL(a) & SR_INT)
401     return 1; /* immidiate int */
402  int s=a->z._mp_alloc;
403//  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  if (!nlIsZero(x))
936  {
937#ifdef LDEBUG
938    nlTest(x);
939#endif
940    number aa=NULL;
941    if (SR_HDL(x) & SR_INT)
942    {
943      aa=nlRInit(SR_TO_INT(x));
944      x=aa;
945    }
946    else if (x->s==0)
947      nlNormalize(x);
948    *u=(number)omAllocBin(rnumber_bin);
949#if defined(LDEBUG)
950    (*u)->debug=123456;
951#endif
952    mpz_init(&(*u)->z);
953    mpz_pow_ui(&(*u)->z,&x->z,(unsigned long)exp);
954    if (x->s<2)
955    {
956      if (mpz_cmp_si(&x->n,(long)1)==0)
957      {
958        x->s=3;
959        mpz_clear(&x->n);
960      }
961      else
962      {
963        mpz_init(&(*u)->n);
964        mpz_pow_ui(&(*u)->n,&x->n,(unsigned long)exp);
965      }
966    }
967    (*u)->s = x->s;
968    if (((*u)->s==3) && (mpz_size1(&(*u)->z)<=MP_SMALL))
969    {
970      int ui=(int)mpz_get_si(&(*u)->z);
971      if ((((ui<<3)>>3)==ui)
972      && (mpz_cmp_si(&(*u)->z,(long)ui)==0))
973      {
974        mpz_clear(&(*u)->z);
975        omFreeBin((ADDRESS)*u, rnumber_bin);
976        *u=INT_TO_SR(ui);
977      }
978    }
979    if (aa!=NULL)
980    {
981      mpz_clear(&aa->z);
982      omFreeBin((ADDRESS)aa, rnumber_bin);
983    }
984  }
985  else
986    *u = INT_TO_SR(0);
987#ifdef LDEBUG
988  nlTest(*u);
989#endif
990}
991
992
993/*2
994* za >= 0 ?
995*/
996BOOLEAN nlGreaterZero (number a)
997{
998#ifdef LDEBUG
999  nlTest(a);
1000#endif
1001  if (SR_HDL(a) & SR_INT) return SR_HDL(a)>1 /* represents number(0) */;
1002  return (!mpz_isNeg(&a->z));
1003}
1004
1005/*2
1006* a > b ?
1007*/
1008BOOLEAN nlGreater (number a, number b)
1009{
1010#ifdef LDEBUG
1011  nlTest(a);
1012  nlTest(b);
1013#endif
1014  number r;
1015  BOOLEAN rr;
1016  r=nlSub(a,b);
1017  rr=(!nlIsZero(r)) && (nlGreaterZero(r));
1018  nlDelete(&r,currRing);
1019  return rr;
1020}
1021
1022/*2
1023* a == -1 ?
1024*/
1025BOOLEAN nlIsMOne (number a)
1026{
1027#ifdef LDEBUG
1028  if (a==NULL) return FALSE;
1029  nlTest(a);
1030#endif
1031  if (SR_HDL(a) & SR_INT) return (a==INT_TO_SR(-1));
1032  return FALSE;
1033}
1034
1035/*2
1036* result =gcd(a,b)
1037*/
1038number nlGcd(number a, number b, const ring r)
1039{
1040  number result;
1041#ifdef LDEBUG
1042  nlTest(a);
1043  nlTest(b);
1044#endif
1045  //nlNormalize(a);
1046  //nlNormalize(b);
1047  if ((a==INT_TO_SR(1))||(a==INT_TO_SR(-1))
1048  ||  (b==INT_TO_SR(1))||(b==INT_TO_SR(-1)))
1049    return INT_TO_SR(1);
1050  if (a==INT_TO_SR(0)) /* gcd(0,b) ->b */
1051    return nlCopy(b);
1052  if (b==INT_TO_SR(0)) /* gcd(a,0) -> a */
1053    return nlCopy(a);
1054  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
1055  {
1056    int i=SR_TO_INT(a);
1057    int j=SR_TO_INT(b);
1058    if((i==0)||(j==0))
1059      return INT_TO_SR(1);
1060    int l;
1061    i=ABS(i);
1062    j=ABS(j);
1063    do
1064    {
1065      l=i%j;
1066      i=j;
1067      j=l;
1068    } while (l!=0);
1069    return INT_TO_SR(i);
1070  }
1071  if (((!(SR_HDL(a) & SR_INT))&&(a->s<2))
1072  ||  ((!(SR_HDL(b) & SR_INT))&&(b->s<2))) return INT_TO_SR(1);
1073  result=(number)omAllocBin(rnumber_bin);
1074#if defined(LDEBUG)
1075  result->debug=123456;
1076#endif
1077  mpz_init(&result->z);
1078  if (SR_HDL(a) & SR_INT)
1079  {
1080    unsigned long t=mpz_gcd_ui(NULL,&b->z,ABS(SR_TO_INT(a)));
1081    return INT_TO_SR((int)t);
1082  }
1083  else
1084  if (SR_HDL(b) & SR_INT)
1085  {
1086    unsigned long t=mpz_gcd_ui(NULL,&a->z,ABS(SR_TO_INT(b)));
1087    return INT_TO_SR((int)t);
1088  }
1089  else
1090  {
1091    mpz_gcd(&result->z,&a->z,&b->z);
1092  }
1093  result->s = 3;
1094  if (mpz_size1(&result->z)<=MP_SMALL)
1095  {
1096    int ui=(int)mpz_get_si(&result->z);
1097    if ((((ui<<3)>>3)==ui)
1098    && (mpz_cmp_si(&result->z,(long)ui)==0))
1099    {
1100      mpz_clear(&result->z);
1101      omFreeBin((ADDRESS)result, rnumber_bin);
1102      result=INT_TO_SR(ui);
1103    }
1104  }
1105#ifdef LDEBUG
1106  nlTest(result);
1107#endif
1108  return result;
1109}
1110
1111/*2
1112* simplify x
1113*/
1114void nlNormalize (number &x)
1115{
1116  if ((SR_HDL(x) & SR_INT) ||(x==NULL))
1117    return;
1118#ifdef LDEBUG
1119  if (!nlTest(x)) { x->s=1; return; }
1120#endif
1121  if (x->s==3)
1122  {
1123    if (mpz_cmp_ui(&x->z,(long)0)==0)
1124    {
1125      nlDelete(&x,currRing);
1126      x=INT_TO_SR(0);
1127      return;
1128    }
1129    if (mpz_size1(&x->z)<=MP_SMALL)
1130    {
1131      int ui=(int)mpz_get_si(&x->z);
1132      if ((((ui<<3)>>3)==ui)
1133      && (mpz_cmp_si(&x->z,(long)ui)==0))
1134      {
1135        mpz_clear(&x->z);
1136        omFreeBin((ADDRESS)x, rnumber_bin);
1137        x=INT_TO_SR(ui);
1138        return;
1139      }
1140    }
1141  }
1142  else if (x->s==0)
1143  {
1144    if (mpz_cmp_si(&x->n,(long)1)==0)
1145    {
1146      mpz_clear(&x->n);
1147      if (mpz_size1(&x->z)<=MP_SMALL)
1148      {
1149        int ui=(int)mpz_get_si(&x->z);
1150        if ((((ui<<3)>>3)==ui)
1151        && (mpz_cmp_si(&x->z,(long)ui)==0))
1152        {
1153          mpz_clear(&x->z);
1154#if defined(LDEBUG)
1155          x->debug=654324;
1156#endif
1157          omFreeBin((ADDRESS)x, rnumber_bin);
1158          x=INT_TO_SR(ui);
1159          return;
1160        }
1161      }
1162      x->s=3;
1163    }
1164    else
1165    {
1166      MP_INT gcd;
1167      mpz_init(&gcd);
1168      mpz_gcd(&gcd,&x->z,&x->n);
1169      x->s=1;
1170      if (mpz_cmp_si(&gcd,(long)1)!=0)
1171      {
1172        MP_INT r;
1173        mpz_init(&r);
1174        MPZ_EXACTDIV(&r,&x->z,&gcd);
1175        mpz_set(&x->z,&r);
1176        MPZ_EXACTDIV(&r,&x->n,&gcd);
1177        mpz_set(&x->n,&r);
1178        mpz_clear(&r);
1179        mpz_clear(&gcd);
1180        if (mpz_cmp_si(&x->n,(long)1)==0)
1181        {
1182          mpz_clear(&x->n);
1183          if (mpz_size1(&x->z)<=MP_SMALL)
1184          {
1185            int ui=(int)mpz_get_si(&x->z);
1186            if ((((ui<<3)>>3)==ui)
1187            && (mpz_cmp_si(&x->z,(long)ui)==0))
1188            {
1189              mpz_clear(&x->z);
1190#if defined(LDEBUG)
1191              x->debug=654324;
1192#endif
1193              omFreeBin((ADDRESS)x, rnumber_bin);
1194              x=INT_TO_SR(ui);
1195              return;
1196            }
1197          }
1198          x->s=3;
1199        }
1200      }
1201    }
1202  }
1203#ifdef LDEBUG
1204  nlTest(x);
1205#endif
1206}
1207
1208/*2
1209* returns in result->z the lcm(a->z,b->n)
1210*/
1211number nlLcm(number a, number b, const ring r)
1212{
1213  number result;
1214#ifdef LDEBUG
1215  nlTest(a);
1216  nlTest(b);
1217#endif
1218  if ((SR_HDL(b) & SR_INT)
1219  || (b->s==3))
1220  {
1221    // b is 1/(b->n) => b->n is 1 => result is a
1222    return nlCopy(a);
1223  }
1224  result=(number)omAllocBin(rnumber_bin);
1225#if defined(LDEBUG)
1226  result->debug=123456;
1227#endif
1228  result->s=3;
1229  MP_INT gcd;
1230  mpz_init(&gcd);
1231  mpz_init(&result->z);
1232  if (SR_HDL(a) & SR_INT)
1233    mpz_gcd_ui(&gcd,&b->n,ABS(SR_TO_INT(a)));
1234  else
1235    mpz_gcd(&gcd,&a->z,&b->n);
1236  if (mpz_cmp_si(&gcd,(long)1)!=0)
1237  {
1238    MP_INT bt;
1239    mpz_init_set(&bt,&b->n);
1240    MPZ_EXACTDIV(&bt,&bt,&gcd);
1241    if (SR_HDL(a) & SR_INT)
1242      mpz_mul_si(&result->z,&bt,SR_TO_INT(a));
1243    else
1244      mpz_mul(&result->z,&bt,&a->z);
1245    mpz_clear(&bt);
1246  }
1247  else
1248    if (SR_HDL(a) & SR_INT)
1249      mpz_mul_si(&result->z,&b->n,SR_TO_INT(a));
1250    else
1251      mpz_mul(&result->z,&b->n,&a->z);
1252  mpz_clear(&gcd);
1253  if (mpz_size1(&result->z)<=MP_SMALL)
1254  {
1255    int ui=(int)mpz_get_si(&result->z);
1256    if ((((ui<<3)>>3)==ui)
1257    && (mpz_cmp_si(&result->z,(long)ui)==0))
1258    {
1259      mpz_clear(&result->z);
1260      omFreeBin((ADDRESS)result, rnumber_bin);
1261      return INT_TO_SR(ui);
1262    }
1263  }
1264#ifdef LDEBUG
1265  nlTest(result);
1266#endif
1267  return result;
1268}
1269
1270int nlModP(number n, int p)
1271{
1272  if (SR_HDL(n) & SR_INT)
1273  {
1274    int i=SR_TO_INT(n);
1275    if (i<0) return (p-((-i)%p));
1276    return i%p;
1277  }
1278  int iz=(int)mpz_mmod_ui(NULL,&n->z,(unsigned long)p);
1279  if (n->s!=3)
1280  {
1281    int in=mpz_mmod_ui(NULL,&n->n,(unsigned long)p);
1282    #ifdef NV_OPS
1283    if (npPrimeM>NV_MAX_PRIME)
1284    return (int)((long)nvDiv((number)iz,(number)in));
1285    #endif
1286    return (int)((long)npDiv((number)iz,(number)in));
1287  }
1288  return iz;
1289}
1290
1291/*2
1292* acces to denominator, other 1 for integers
1293*/
1294number   nlGetDenom(number &n, const ring r)
1295{
1296  if (!(SR_HDL(n) & SR_INT))
1297  {
1298    if (n->s==0)
1299    {
1300      nlNormalize(n);
1301    }
1302    if (!(SR_HDL(n) & SR_INT))
1303    {
1304      if (n->s!=3)
1305      {
1306        number u=(number)omAllocBin(rnumber_bin);
1307        u->s=3;
1308#if defined(LDEBUG)
1309        u->debug=123456;
1310#endif
1311        mpz_init_set(&u->z,&n->n);
1312        {
1313          int ui=(int)mpz_get_si(&u->z);
1314          if ((((ui<<3)>>3)==ui)
1315          && (mpz_cmp_si(&u->z,(long)ui)==0))
1316          {
1317            mpz_clear(&u->z);
1318            omFreeBin((ADDRESS)u, rnumber_bin);
1319            return INT_TO_SR(ui);
1320          }
1321        }
1322        return u;
1323      }
1324    }
1325  }
1326  return INT_TO_SR(1);
1327}
1328
1329/*2
1330* acces to Nominator, nlCopy(n) for integers
1331*/
1332number   nlGetNom(number &n, const ring r)
1333{
1334  if (!(SR_HDL(n) & SR_INT))
1335  {
1336    if (n->s==0)
1337    {
1338      nlNormalize(n);
1339    }
1340    if (!(SR_HDL(n) & SR_INT))
1341    {
1342      number u=(number)omAllocBin(rnumber_bin);
1343#if defined(LDEBUG)
1344      u->debug=123456;
1345#endif
1346      u->s=3;
1347      mpz_init_set(&u->z,&n->z);
1348      if (n->s!=3)
1349      {
1350        int ui=(int)mpz_get_si(&u->z);
1351        if ((((ui<<3)>>3)==ui)
1352        && (mpz_cmp_si(&u->z,(long)ui)==0))
1353        {
1354          mpz_clear(&u->z);
1355          omFreeBin((ADDRESS)u, rnumber_bin);
1356          return INT_TO_SR(ui);
1357        }
1358      }
1359      return u;
1360    }
1361  }
1362  return n; // imm. int
1363}
1364
1365/***************************************************************
1366 *
1367 * routines which are needed by Inline(d) routines
1368 *
1369 *******************************************************************/
1370BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b)
1371{
1372  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
1373//  long - short
1374  BOOLEAN bo;
1375  if (SR_HDL(b) & SR_INT)
1376  {
1377    if (a->s!=0) return FALSE;
1378    number n=b; b=a; a=n;
1379  }
1380//  short - long
1381  if (SR_HDL(a) & SR_INT)
1382  {
1383    if (b->s!=0)
1384      return FALSE;
1385    if (((long)a > 0L) && (mpz_isNeg(&b->z)))
1386      return FALSE;
1387    if (((long)a < 0L) && (!mpz_isNeg(&b->z)))
1388      return FALSE;
1389    MP_INT  bb;
1390    mpz_init_set(&bb,&b->n);
1391    mpz_mul_si(&bb,&bb,(long)SR_TO_INT(a));
1392    bo=(mpz_cmp(&bb,&b->z)==0);
1393    mpz_clear(&bb);
1394    return bo;
1395  }
1396// long - long
1397  if (((a->s==1) && (b->s==3))
1398  ||  ((b->s==1) && (a->s==3)))
1399    return FALSE;
1400  if (mpz_isNeg(&a->z)&&(!mpz_isNeg(&b->z)))
1401    return FALSE;
1402  if (mpz_isNeg(&b->z)&&(!mpz_isNeg(&a->z)))
1403    return FALSE;
1404  MP_INT  aa;
1405  MP_INT  bb;
1406  mpz_init_set(&aa,&a->z);
1407  mpz_init_set(&bb,&b->z);
1408  if (a->s<2) mpz_mul(&bb,&bb,&a->n);
1409  if (b->s<2) mpz_mul(&aa,&aa,&b->n);
1410  bo=(mpz_cmp(&aa,&bb)==0);
1411  mpz_clear(&aa);
1412  mpz_clear(&bb);
1413  return bo;
1414}
1415
1416// copy not immediate number a
1417number _nlCopy_NoImm(number a)
1418{
1419  assume(!((SR_HDL(a) & SR_INT)||(a==NULL)));
1420#ifdef LDEBUG
1421  nlTest(a);
1422#endif
1423  number b=(number)omAllocBin(rnumber_bin);
1424#if defined(LDEBUG)
1425  b->debug=123456;
1426#endif
1427  switch (a->s)
1428  {
1429    case 0:
1430    case 1:
1431            mpz_init_set(&b->n,&a->n);
1432    case 3:
1433            mpz_init_set(&b->z,&a->z);
1434            break;
1435  }
1436  b->s = a->s;
1437#ifdef LDEBUG
1438  nlTest(b);
1439#endif
1440  return b;
1441}
1442
1443void _nlDelete_NoImm(number *a, const ring r)
1444{
1445  {
1446    switch ((*a)->s)
1447    {
1448      case 0:
1449      case 1:
1450        mpz_clear(&(*a)->n);
1451      case 3:
1452        mpz_clear(&(*a)->z);
1453#ifdef LDEBUG
1454        (*a)->s=2;
1455#endif
1456    }
1457    omFreeBin((ADDRESS) *a, rnumber_bin);
1458  }
1459}
1460
1461number _nlNeg_NoImm(number a)
1462{
1463  {
1464    mpz_neg(&a->z,&a->z);
1465    if ((a->s==3) && (mpz_size1(&a->z)<=MP_SMALL))
1466    {
1467      int ui=(int)mpz_get_si(&a->z);
1468      if ((((ui<<3)>>3)==ui)
1469        && (mpz_cmp_si(&a->z,(long)ui)==0))
1470      {
1471        mpz_clear(&a->z);
1472        omFreeBin((ADDRESS)a, rnumber_bin);
1473        a=INT_TO_SR(ui);
1474      }
1475    }
1476  }
1477#ifdef LDEBUG
1478  nlTest(a);
1479#endif
1480  return a;
1481}
1482
1483number _nlAdd_aNoImm_OR_bNoImm(number a, number b)
1484{
1485  number u=(number)omAllocBin(rnumber_bin);
1486#if defined(LDEBUG)
1487  u->debug=123456;
1488#endif
1489  mpz_init(&u->z);
1490  if (SR_HDL(b) & SR_INT)
1491  {
1492    number x=a;
1493    a=b;
1494    b=x;
1495  }
1496  if (SR_HDL(a) & SR_INT)
1497  {
1498    switch (b->s)
1499    {
1500      case 0:
1501      case 1:/* a:short, b:1 */
1502      {
1503        MP_INT x;
1504        mpz_init(&x);
1505        mpz_mul_si(&x,&b->n,SR_TO_INT(a));
1506        mpz_add(&u->z,&b->z,&x);
1507        mpz_clear(&x);
1508        if (mpz_cmp_ui(&u->z,(long)0)==0)
1509        {
1510          mpz_clear(&u->z);
1511          omFreeBin((ADDRESS)u, rnumber_bin);
1512          return INT_TO_SR(0);
1513        }
1514        if (mpz_cmp(&u->z,&b->n)==0)
1515        {
1516          mpz_clear(&u->z);
1517          omFreeBin((ADDRESS)u, rnumber_bin);
1518          return INT_TO_SR(1);
1519        }
1520        mpz_init_set(&u->n,&b->n);
1521        u->s = 0;
1522        break;
1523      }
1524      case 3:
1525      {
1526        if ((long)a>0L)
1527          mpz_add_ui(&u->z,&b->z,SR_TO_INT(a));
1528        else
1529          mpz_sub_ui(&u->z,&b->z,-SR_TO_INT(a));
1530        if (mpz_cmp_ui(&u->z,(long)0)==0)
1531        {
1532          mpz_clear(&u->z);
1533          omFreeBin((ADDRESS)u, rnumber_bin);
1534          return INT_TO_SR(0);
1535        }
1536        //u->s = 3;
1537        if (mpz_size1(&u->z)<=MP_SMALL)
1538        {
1539          int ui=(int)mpz_get_si(&u->z);
1540          if ((((ui<<3)>>3)==ui)
1541          && (mpz_cmp_si(&u->z,(long)ui)==0))
1542          {
1543            mpz_clear(&u->z);
1544            omFreeBin((ADDRESS)u, rnumber_bin);
1545            return INT_TO_SR(ui);
1546          }
1547        }
1548        u->s = 3;
1549        break;
1550      }
1551    }
1552  }
1553  else
1554  {
1555    switch (a->s)
1556    {
1557      case 0:
1558      case 1:
1559      {
1560        switch(b->s)
1561        {
1562          case 0:
1563          case 1:
1564          {
1565            MP_INT x;
1566            MP_INT y;
1567            mpz_init(&x);
1568            mpz_init(&y);
1569            mpz_mul(&x,&b->z,&a->n);
1570            mpz_mul(&y,&a->z,&b->n);
1571            mpz_add(&u->z,&x,&y);
1572            mpz_clear(&x);
1573            mpz_clear(&y);
1574            if (mpz_cmp_ui(&u->z,(long)0)==0)
1575            {
1576              mpz_clear(&u->z);
1577              omFreeBin((ADDRESS)u, rnumber_bin);
1578              return INT_TO_SR(0);
1579            }
1580            mpz_init(&u->n);
1581            mpz_mul(&u->n,&a->n,&b->n);
1582            if (mpz_cmp(&u->z,&u->n)==0)
1583            {
1584               mpz_clear(&u->z);
1585               mpz_clear(&u->n);
1586               omFreeBin((ADDRESS)u, rnumber_bin);
1587               return INT_TO_SR(1);
1588            }
1589            u->s = 0;
1590            break;
1591          }
1592          case 3: /* a:1 b:3 */
1593          {
1594            MP_INT x;
1595            mpz_init(&x);
1596            mpz_mul(&x,&b->z,&a->n);
1597            mpz_add(&u->z,&a->z,&x);
1598            mpz_clear(&x);
1599            if (mpz_cmp_ui(&u->z,(long)0)==0)
1600            {
1601              mpz_clear(&u->z);
1602              omFreeBin((ADDRESS)u, rnumber_bin);
1603              return INT_TO_SR(0);
1604            }
1605            if (mpz_cmp(&u->z,&a->n)==0)
1606            {
1607              mpz_clear(&u->z);
1608              omFreeBin((ADDRESS)u, rnumber_bin);
1609              return INT_TO_SR(1);
1610            }
1611            mpz_init_set(&u->n,&a->n);
1612            u->s = 0;
1613            break;
1614          }
1615        } /*switch (b->s) */
1616        break;
1617      }
1618      case 3:
1619      {
1620        switch(b->s)
1621        {
1622          case 0:
1623          case 1:/* a:3, b:1 */
1624          {
1625            MP_INT x;
1626            mpz_init(&x);
1627            mpz_mul(&x,&a->z,&b->n);
1628            mpz_add(&u->z,&b->z,&x);
1629            mpz_clear(&x);
1630            if (mpz_cmp_ui(&u->z,(long)0)==0)
1631            {
1632              mpz_clear(&u->z);
1633              omFreeBin((ADDRESS)u, rnumber_bin);
1634              return INT_TO_SR(0);
1635            }
1636            if (mpz_cmp(&u->z,&b->n)==0)
1637            {
1638              mpz_clear(&u->z);
1639              omFreeBin((ADDRESS)u, rnumber_bin);
1640              return INT_TO_SR(1);
1641            }
1642            mpz_init_set(&u->n,&b->n);
1643            u->s = 0;
1644            break;
1645          }
1646          case 3:
1647          {
1648            mpz_add(&u->z,&a->z,&b->z);
1649            if (mpz_cmp_ui(&u->z,(long)0)==0)
1650            {
1651              mpz_clear(&u->z);
1652              omFreeBin((ADDRESS)u, rnumber_bin);
1653              return INT_TO_SR(0);
1654            }
1655            if (mpz_size1(&u->z)<=MP_SMALL)
1656            {
1657              int ui=(int)mpz_get_si(&u->z);
1658              if ((((ui<<3)>>3)==ui)
1659              && (mpz_cmp_si(&u->z,(long)ui)==0))
1660              {
1661                mpz_clear(&u->z);
1662                omFreeBin((ADDRESS)u, rnumber_bin);
1663                return INT_TO_SR(ui);
1664              }
1665            }
1666            u->s = 3;
1667            break;
1668          }
1669        }
1670        break;
1671      }
1672    }
1673  }
1674#ifdef LDEBUG
1675  nlTest(u);
1676#endif
1677  return u;
1678}
1679
1680number _nlSub_aNoImm_OR_bNoImm(number a, number b)
1681{
1682  number u=(number)omAllocBin(rnumber_bin);
1683#if defined(LDEBUG)
1684  u->debug=123456;
1685#endif
1686  mpz_init(&u->z);
1687  if (SR_HDL(a) & SR_INT)
1688  {
1689    switch (b->s)
1690    {
1691      case 0:
1692      case 1:/* a:short, b:1 */
1693      {
1694        MP_INT x;
1695        mpz_init(&x);
1696        mpz_mul_si(&x,&b->n,SR_TO_INT(a));
1697        mpz_sub(&u->z,&x,&b->z);
1698        mpz_clear(&x);
1699        if (mpz_cmp_ui(&u->z,(long)0)==0)
1700        {
1701          mpz_clear(&u->z);
1702          omFreeBin((ADDRESS)u, rnumber_bin);
1703          return INT_TO_SR(0);
1704        }
1705        if (mpz_cmp(&u->z,&b->n)==0)
1706        {
1707          mpz_clear(&u->z);
1708          omFreeBin((ADDRESS)u, rnumber_bin);
1709          return INT_TO_SR(1);
1710        }
1711        mpz_init_set(&u->n,&b->n);
1712        u->s = 0;
1713        break;
1714      }
1715      case 3:
1716      {
1717        if ((long)a>0L)
1718        {
1719          mpz_sub_ui(&u->z,&b->z,SR_TO_INT(a));
1720          mpz_neg(&u->z,&u->z);
1721        }
1722        else
1723        {
1724          mpz_add_ui(&u->z,&b->z,-SR_TO_INT(a));
1725          mpz_neg(&u->z,&u->z);
1726        }
1727        if (mpz_cmp_ui(&u->z,(long)0)==0)
1728        {
1729          mpz_clear(&u->z);
1730          omFreeBin((ADDRESS)u, rnumber_bin);
1731          return INT_TO_SR(0);
1732        }
1733        if (mpz_size1(&u->z)<=MP_SMALL)
1734        {
1735          int ui=(int)mpz_get_si(&u->z);
1736          if ((((ui<<3)>>3)==ui)
1737          && (mpz_cmp_si(&u->z,(long)ui)==0))
1738          {
1739            mpz_clear(&u->z);
1740            omFreeBin((ADDRESS)u, rnumber_bin);
1741            return INT_TO_SR(ui);
1742          }
1743        }
1744        u->s = 3;
1745        break;
1746      }
1747    }
1748  }
1749  else if (SR_HDL(b) & SR_INT)
1750  {
1751    switch (a->s)
1752    {
1753      case 0:
1754      case 1:/* b:short, a:1 */
1755      {
1756        MP_INT x;
1757        mpz_init(&x);
1758        mpz_mul_si(&x,&a->n,SR_TO_INT(b));
1759        mpz_sub(&u->z,&a->z,&x);
1760        mpz_clear(&x);
1761        if (mpz_cmp_ui(&u->z,(long)0)==0)
1762        {
1763          mpz_clear(&u->z);
1764          omFreeBin((ADDRESS)u, rnumber_bin);
1765          return INT_TO_SR(0);
1766        }
1767        if (mpz_cmp(&u->z,&a->n)==0)
1768        {
1769          mpz_clear(&u->z);
1770          omFreeBin((ADDRESS)u, rnumber_bin);
1771          return INT_TO_SR(1);
1772        }
1773        mpz_init_set(&u->n,&a->n);
1774        u->s = 0;
1775        break;
1776      }
1777      case 3:
1778      {
1779        if ((long)b>0L)
1780        {
1781          mpz_sub_ui(&u->z,&a->z,SR_TO_INT(b));
1782        }
1783        else
1784        {
1785          mpz_add_ui(&u->z,&a->z,-SR_TO_INT(b));
1786        }
1787        if (mpz_cmp_ui(&u->z,(long)0)==0)
1788        {
1789          mpz_clear(&u->z);
1790          omFreeBin((ADDRESS)u, rnumber_bin);
1791          return INT_TO_SR(0);
1792        }
1793        //u->s = 3;
1794        if (mpz_size1(&u->z)<=MP_SMALL)
1795        {
1796          int ui=(int)mpz_get_si(&u->z);
1797          if ((((ui<<3)>>3)==ui)
1798          && (mpz_cmp_si(&u->z,(long)ui)==0))
1799          {
1800            mpz_clear(&u->z);
1801            omFreeBin((ADDRESS)u, rnumber_bin);
1802            return INT_TO_SR(ui);
1803          }
1804        }
1805        u->s = 3;
1806        break;
1807      }
1808    }
1809  }
1810  else
1811  {
1812    switch (a->s)
1813    {
1814      case 0:
1815      case 1:
1816      {
1817        switch(b->s)
1818        {
1819          case 0:
1820          case 1:
1821          {
1822            MP_INT x;
1823            MP_INT y;
1824            mpz_init(&x);
1825            mpz_init(&y);
1826            mpz_mul(&x,&b->z,&a->n);
1827            mpz_mul(&y,&a->z,&b->n);
1828            mpz_sub(&u->z,&y,&x);
1829            mpz_clear(&x);
1830            mpz_clear(&y);
1831            if (mpz_cmp_ui(&u->z,(long)0)==0)
1832            {
1833              mpz_clear(&u->z);
1834              omFreeBin((ADDRESS)u, rnumber_bin);
1835              return INT_TO_SR(0);
1836            }
1837            mpz_init(&u->n);
1838            mpz_mul(&u->n,&a->n,&b->n);
1839            if (mpz_cmp(&u->z,&u->n)==0)
1840            {
1841              mpz_clear(&u->z);
1842              mpz_clear(&u->n);
1843              omFreeBin((ADDRESS)u, rnumber_bin);
1844              return INT_TO_SR(1);
1845            }
1846            u->s = 0;
1847            break;
1848          }
1849          case 3: /* a:1, b:3 */
1850          {
1851            MP_INT x;
1852            mpz_init(&x);
1853            mpz_mul(&x,&b->z,&a->n);
1854            mpz_sub(&u->z,&a->z,&x);
1855            mpz_clear(&x);
1856            if (mpz_cmp_ui(&u->z,(long)0)==0)
1857            {
1858              mpz_clear(&u->z);
1859              omFreeBin((ADDRESS)u, rnumber_bin);
1860              return INT_TO_SR(0);
1861            }
1862            if (mpz_cmp(&u->z,&a->n)==0)
1863            {
1864              mpz_clear(&u->z);
1865              omFreeBin((ADDRESS)u, rnumber_bin);
1866              return INT_TO_SR(1);
1867            }
1868            mpz_init_set(&u->n,&a->n);
1869            u->s = 0;
1870            break;
1871          }
1872        }
1873        break;
1874      }
1875      case 3:
1876      {
1877        switch(b->s)
1878        {
1879          case 0:
1880          case 1: /* a:3, b:1 */
1881          {
1882            MP_INT x;
1883            mpz_init(&x);
1884            mpz_mul(&x,&a->z,&b->n);
1885            mpz_sub(&u->z,&x,&b->z);
1886            mpz_clear(&x);
1887            if (mpz_cmp_ui(&u->z,(long)0)==0)
1888            {
1889              mpz_clear(&u->z);
1890              omFreeBin((ADDRESS)u, rnumber_bin);
1891              return INT_TO_SR(0);
1892            }
1893            if (mpz_cmp(&u->z,&b->n)==0)
1894            {
1895              mpz_clear(&u->z);
1896              omFreeBin((ADDRESS)u, rnumber_bin);
1897              return INT_TO_SR(1);
1898            }
1899            mpz_init_set(&u->n,&b->n);
1900            u->s = 0;
1901            break;
1902          }
1903          case 3: /* a:3 , b:3 */
1904          {
1905            mpz_sub(&u->z,&a->z,&b->z);
1906            if (mpz_cmp_ui(&u->z,(long)0)==0)
1907            {
1908              mpz_clear(&u->z);
1909              omFreeBin((ADDRESS)u, rnumber_bin);
1910              return INT_TO_SR(0);
1911            }
1912            //u->s = 3;
1913            if (mpz_size1(&u->z)<=MP_SMALL)
1914            {
1915              int ui=(int)mpz_get_si(&u->z);
1916              if ((((ui<<3)>>3)==ui)
1917              && (mpz_cmp_si(&u->z,(long)ui)==0))
1918              {
1919                mpz_clear(&u->z);
1920                omFreeBin((ADDRESS)u, rnumber_bin);
1921                return INT_TO_SR(ui);
1922              }
1923            }
1924            u->s = 3;
1925            break;
1926          }
1927        }
1928        break;
1929      }
1930    }
1931  }
1932#ifdef LDEBUG
1933  nlTest(u);
1934#endif
1935  return u;
1936}
1937
1938// a and b are intermediate, but a*b not
1939number _nlMult_aImm_bImm_rNoImm(number a, number b)
1940{
1941  number u=(number)omAllocBin(rnumber_bin);
1942#if defined(LDEBUG)
1943  u->debug=123456;
1944#endif
1945  u->s=3;
1946  mpz_init_set_si(&u->z,(long)SR_TO_INT(a));
1947  mpz_mul_si(&u->z,&u->z,(long)SR_TO_INT(b));
1948#ifdef LDEBUG
1949  nlTest(u);
1950#endif
1951  return u;
1952}
1953
1954// a or b are not immediate
1955number _nlMult_aNoImm_OR_bNoImm(number a, number b)
1956{
1957  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
1958  number u=(number)omAllocBin(rnumber_bin);
1959#if defined(LDEBUG)
1960  u->debug=123456;
1961#endif
1962  mpz_init(&u->z);
1963  if (SR_HDL(b) & SR_INT)
1964  {
1965    number x=a;
1966    a=b;
1967    b=x;
1968  }
1969  if (SR_HDL(a) & SR_INT)
1970  {
1971    u->s=b->s;
1972    if (u->s==1) u->s=0;
1973    if ((long)a>0L)
1974    {
1975      mpz_mul_ui(&u->z,&b->z,(unsigned long)SR_TO_INT(a));
1976    }
1977    else
1978    {
1979      if (a==INT_TO_SR(-1))
1980      {
1981        mpz_set(&u->z,&b->z);
1982        mpz_neg(&u->z,&u->z);
1983        u->s=b->s;
1984      }
1985      else
1986      {
1987        mpz_mul_ui(&u->z,&b->z,(unsigned long)-SR_TO_INT(a));
1988        mpz_neg(&u->z,&u->z);
1989      }
1990    }
1991    if (u->s<2)
1992    {
1993      if (mpz_cmp(&u->z,&b->n)==0)
1994      {
1995        mpz_clear(&u->z);
1996        omFreeBin((ADDRESS)u, rnumber_bin);
1997        return INT_TO_SR(1);
1998      }
1999      mpz_init_set(&u->n,&b->n);
2000    }
2001    else //u->s==3
2002    {
2003      if (mpz_size1(&u->z)<=MP_SMALL)
2004      {
2005        int ui=(int)mpz_get_si(&u->z);
2006        if ((((ui<<3)>>3)==ui)
2007            && (mpz_cmp_si(&u->z,(long)ui)==0))
2008        {
2009          mpz_clear(&u->z);
2010          omFreeBin((ADDRESS)u, rnumber_bin);
2011          return INT_TO_SR(ui);
2012        }
2013      }
2014    }
2015  }
2016  else
2017  {
2018    mpz_mul(&u->z,&a->z,&b->z);
2019    u->s = 0;
2020    if(a->s==3)
2021    {
2022      if(b->s==3)
2023      {
2024        u->s = 3;
2025      }
2026      else
2027      {
2028        if (mpz_cmp(&u->z,&b->n)==0)
2029        {
2030          mpz_clear(&u->z);
2031          omFreeBin((ADDRESS)u, rnumber_bin);
2032          return INT_TO_SR(1);
2033        }
2034        mpz_init_set(&u->n,&b->n);
2035      }
2036    }
2037    else
2038    {
2039      if(b->s==3)
2040      {
2041        if (mpz_cmp(&u->z,&a->n)==0)
2042        {
2043          mpz_clear(&u->z);
2044          omFreeBin((ADDRESS)u, rnumber_bin);
2045          return INT_TO_SR(1);
2046        }
2047        mpz_init_set(&u->n,&a->n);
2048      }
2049      else
2050      {
2051        mpz_init(&u->n);
2052        mpz_mul(&u->n,&a->n,&b->n);
2053        if (mpz_cmp(&u->z,&u->n)==0)
2054        {
2055          mpz_clear(&u->z);
2056          mpz_clear(&u->n);
2057          omFreeBin((ADDRESS)u, rnumber_bin);
2058          return INT_TO_SR(1);
2059        }
2060      }
2061    }
2062  }
2063#ifdef LDEBUG
2064  nlTest(u);
2065#endif
2066  return u;
2067}
2068
2069/*2
2070* z := i
2071*/
2072number nlRInit (int i)
2073{
2074  number z=(number)omAllocBin(rnumber_bin);
2075#if defined(LDEBUG)
2076  z->debug=123456;
2077#endif
2078  mpz_init_set_si(&z->z,(long)i);
2079  z->s = 3;
2080  return z;
2081}
2082
2083/*2
2084* z := i/j
2085*/
2086number nlInit2 (int i, int j)
2087{
2088  number z=(number)omAllocBin(rnumber_bin);
2089#if defined(LDEBUG)
2090  z->debug=123456;
2091#endif
2092  mpz_init_set_si(&z->z,(long)i);
2093  mpz_init_set_si(&z->n,(long)j);
2094  z->s = 0;
2095  nlNormalize(z);
2096  return z;
2097}
2098
2099number nlInit2gmp (mpz_t i, mpz_t j)
2100{
2101  number z=(number)omAllocBin(rnumber_bin);
2102#if defined(LDEBUG)
2103  z->debug=123456;
2104#endif
2105  mpz_init_set(&z->z,i);
2106  mpz_init_set(&z->n,j);
2107  z->s = 0;
2108  nlNormalize(z);
2109  return z;
2110}
2111
2112#else // DO_LINLINE
2113
2114// declare immedate routines
2115number nlRInit (int i);
2116BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b);
2117number  _nlCopy_NoImm(number a);
2118void    _nlDelete_NoImm(number *a, const ring r);
2119number  _nlNeg_NoImm(number a);
2120number  _nlAdd_aNoImm_OR_bNoImm(number a, number b);
2121number  _nlSub_aNoImm_OR_bNoImm(number a, number b);
2122number  _nlMult_aNoImm_OR_bNoImm(number a, number b);
2123number  _nlMult_aImm_bImm_rNoImm(number a, number b);
2124
2125#endif
2126
2127
2128/***************************************************************
2129 *
2130 * Routines which might be inlined by p_Numbers.h
2131 *
2132 *******************************************************************/
2133#if defined(DO_LINLINE) || !defined(P_NUMBERS_H)
2134
2135// routines which are always inlined/static
2136
2137/*2
2138* a = b ?
2139*/
2140LINLINE BOOLEAN nlEqual (number a, number b)
2141{
2142#ifdef LDEBUG
2143  nlTest(a);
2144  nlTest(b);
2145#endif
2146// short - short
2147  if (SR_HDL(a) & SR_HDL(b) & SR_INT) return a==b;
2148  return _nlEqual_aNoImm_OR_bNoImm(a, b);
2149}
2150
2151
2152LINLINE number nlInit (int i)
2153{
2154  number n;
2155  if ( ((i << 3) >> 3) == i ) n=INT_TO_SR(i);
2156  else                        n=nlRInit(i);
2157#ifdef LDEBUG
2158  nlTest(n);
2159#endif
2160  return n;
2161}
2162
2163
2164/*2
2165* a == 1 ?
2166*/
2167LINLINE BOOLEAN nlIsOne (number a)
2168{
2169#ifdef LDEBUG
2170  if (a==NULL) return FALSE;
2171  nlTest(a);
2172#endif
2173  if (SR_HDL(a) & SR_INT) return (a==INT_TO_SR(1));
2174  return FALSE;
2175}
2176
2177LINLINE BOOLEAN nlIsZero (number a)
2178{
2179  return (a==INT_TO_SR(0));
2180}
2181
2182/*2
2183* copy a to b
2184*/
2185LINLINE number nlCopy(number a)
2186{
2187  if ((SR_HDL(a) & SR_INT)||(a==NULL))
2188  {
2189    return a;
2190  }
2191  return _nlCopy_NoImm(a);
2192}
2193
2194
2195LINLINE void nlNew (number * r)
2196{
2197  *r=NULL;
2198}
2199
2200/*2
2201* delete a
2202*/
2203LINLINE void nlDelete (number * a, const ring r)
2204{
2205  if (*a!=NULL)
2206  {
2207#ifdef LDEBUG
2208    nlTest(*a);
2209#endif
2210    if ((SR_HDL(*a) & SR_INT)==0)
2211    {
2212      _nlDelete_NoImm(a,r);
2213    }
2214    *a=NULL;
2215  }
2216}
2217
2218/*2
2219* za:= - za
2220*/
2221LINLINE number nlNeg (number a)
2222{
2223#ifdef LDEBUG
2224  nlTest(a);
2225#endif
2226  if(SR_HDL(a) &SR_INT)
2227  {
2228    int r=SR_TO_INT(a);
2229    if (r==(-(1<<28))) a=nlRInit(1<<28);
2230    else               a=INT_TO_SR(-r);
2231    return a;
2232  }
2233  return _nlNeg_NoImm(a);
2234}
2235
2236/*2
2237* u:= a + b
2238*/
2239LINLINE number nlAdd (number a, number b)
2240{
2241  number u;
2242  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2243  {
2244    int r=SR_HDL(a)+SR_HDL(b)-1;
2245    if ( ((r << 1) >> 1) == r )
2246      return (number)(long)r;
2247    else
2248      return nlRInit(SR_TO_INT(r));
2249  }
2250  return _nlAdd_aNoImm_OR_bNoImm(a, b);
2251}
2252
2253LINLINE number nlMult (number a, number b)
2254{
2255#ifdef LDEBUG
2256  nlTest(a);
2257  nlTest(b);
2258#endif
2259  if (a==INT_TO_SR(0)) return INT_TO_SR(0);
2260  if (b==INT_TO_SR(0)) return INT_TO_SR(0);
2261  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2262  {
2263    int r=(SR_HDL(a)-1)*(SR_HDL(b)>>1);
2264    if ((r/(SR_HDL(b)>>1))==(SR_HDL(a)-1))
2265    {
2266      number u=((number) ((r>>1)+SR_INT));
2267      if (((SR_HDL(u)<<1)>>1)==SR_HDL(u)) return (u);
2268      return nlRInit(SR_HDL(u)>>2);
2269    }
2270    return _nlMult_aImm_bImm_rNoImm(a, b);
2271  }
2272  return _nlMult_aNoImm_OR_bNoImm(a, b);
2273}
2274
2275
2276/*2
2277* u:= a - b
2278*/
2279LINLINE number nlSub (number a, number b)
2280{
2281  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2282  {
2283    int r=SR_HDL(a)-SR_HDL(b)+1;
2284    if ( ((r << 1) >> 1) == r )
2285    {
2286      return (number)r;
2287    }
2288    else
2289      return nlRInit(SR_TO_INT(r));
2290  }
2291  return _nlSub_aNoImm_OR_bNoImm(a, b);
2292}
2293
2294#endif // DO_LINLINE
2295
2296#ifndef P_NUMBERS_H
2297
2298void nlInpGcd(number &a, number b, ring r)
2299{
2300  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2301  {
2302    number n=nlGcd(a,b,r);
2303    nlDelete(&a,r);
2304    a=n;
2305  }
2306  else
2307  {
2308    mpz_gcd(&a->z,&a->z,&b->z);
2309    if (mpz_size1(&a->z)<=MP_SMALL)
2310    {
2311      int ui=(int)mpz_get_si(&a->z);
2312      if ((((ui<<3)>>3)==ui)
2313      && (mpz_cmp_si(&a->z,(long)ui)==0))
2314      {
2315        mpz_clear(&a->z);
2316        omFreeBin((ADDRESS)a, rnumber_bin);
2317        a=INT_TO_SR(ui);
2318      }
2319    }
2320  }
2321}
2322void nlInpIntDiv(number &a, number b, ring r)
2323{
2324  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2325  {
2326    number n=nlIntDiv(a,b);
2327    nlDelete(&a,r);
2328    a=n;
2329  }
2330  else
2331  {
2332    if (mpz_isNeg(&a->z))
2333    {
2334      if (mpz_isNeg(&b->z))
2335      {
2336        mpz_add(&a->z,&a->z,&b->z);
2337      }
2338      else
2339      {
2340        mpz_sub(&a->z,&a->z,&b->z);
2341      }
2342      mpz_add_ui(&a->z,&a->z,1);
2343    }
2344    else
2345    {
2346      if (mpz_isNeg(&b->z))
2347      {
2348        mpz_sub(&a->z,&a->z,&b->z);
2349      }
2350      else
2351      {
2352        mpz_add(&a->z,&a->z,&b->z);
2353      }
2354      mpz_sub_ui(&a->z,&a->z,1);
2355    }
2356    MPZ_DIV(&a->z,&a->z,&b->z);
2357    if (mpz_size1(&a->z)<=MP_SMALL)
2358    {
2359      int ui=(int)mpz_get_si(&a->z);
2360      if ((((ui<<3)>>3)==ui)
2361      && (mpz_cmp_si(&a->z,(long)ui)==0))
2362      {
2363        mpz_clear(&a->z);
2364        omFreeBin((ADDRESS)a, rnumber_bin);
2365        a=INT_TO_SR(ui);
2366      }
2367    }
2368  }
2369}
2370void nlInpAdd(number &a, number b, ring r)
2371{
2372  // TODO
2373  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2374  {
2375    number n=nlGcd(a,b,r);
2376    nlDelete(&a,r);
2377    a=n;
2378  }
2379  else
2380  {
2381    mpz_gcd(&a->z,&a->z,&b->z);
2382    if (mpz_size1(&a->z)<=MP_SMALL)
2383    {
2384      int ui=(int)mpz_get_si(&a->z);
2385      if ((((ui<<3)>>3)==ui)
2386      && (mpz_cmp_si(&a->z,(long)ui)==0))
2387      {
2388        mpz_clear(&a->z);
2389        omFreeBin((ADDRESS)a, rnumber_bin);
2390        a=INT_TO_SR(ui);
2391      }
2392    }
2393  }
2394}
2395void nlInpMult(number &a, number b, ring r)
2396{
2397  if (((SR_HDL(b)|SR_HDL(a))&SR_INT)
2398  )
2399  {
2400    number n=nlMult(a,b);
2401    nlDelete(&a,r);
2402    a=n;
2403  }
2404  else
2405  {
2406    mpz_mul(&a->z,&a->z,&b->z);
2407    if (a->s==3)
2408    {
2409      if(b->s!=3)
2410      {
2411        mpz_init_set(&a->n,&b->n);
2412        a->s=0;
2413      }
2414    }
2415    else
2416    {
2417      if(b->s!=3)
2418      {
2419        mpz_mul(&a->n,&a->n,&b->n);
2420      }
2421      a->s=0;
2422    }
2423  }
2424}
2425
2426#if 0
2427number nlMod(number a, number b)
2428{
2429  if (((SR_HDL(b)&SR_HDL(a))&SR_INT)
2430  {
2431    int bi=SR_TO_INT(b);
2432    int ai=SR_TO_INT(a);
2433    int bb=ABS(bi);
2434    int c=ai%bb;
2435    if (c<0)  c+=bb;
2436    return (INT_TO_SR(c));
2437  }
2438  number al;
2439  number bl;
2440  if (SR_HDL(a))&SR_INT)
2441    al=nlRInit(SR_TO_INT(a));
2442  else
2443    al=nlCopy(a);
2444  if (SR_HDL(b))&SR_INT)
2445    bl=nlRInit(SR_TO_INT(b));
2446  else
2447    bl=nlCopy(b);
2448  number r=nlRInit(0);
2449  mpz_mod(r->z,al->z,bl->z);
2450  nlDelete(&al);
2451  nlDelete(&bl);
2452  if (mpz_size1(&r->z)<=MP_SMALL)
2453  {
2454    int ui=(int)mpz_get_si(&r->z);
2455    if ((((ui<<3)>>3)==ui)
2456    && (mpz_cmp_si(&x->z,(long)ui)==0))
2457    {
2458      mpz_clear(&r->z);
2459      omFreeBin((ADDRESS)r, rnumber_bin);
2460      r=INT_TO_SR(ui);
2461    }
2462  }
2463  return r;
2464}
2465#endif
2466#endif // not P_NUMBERS_H
2467#endif // LONGRAT_CC
Note: See TracBrowser for help on using the repository browser.