source: git/kernel/longrat.cc @ 87353a6

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