source: git/coeffs/longrat.cc @ a642c64

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