source: git/coeffs/longrat.cc @ 31213a4

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