source: git/coeffs/longrat.cc @ fa31d2

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