source: git/libpolys/coeffs/longrat.cc @ 7152fa

spielwiese
Last change on this file since 7152fa was 7152fa, checked in by Hans Schoenemann <hannes@…>, 10 years ago
more changes for 64bit: number representation in Q
  • Property mode set to 100644
File size: 63.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: computation with long rational numbers (Hubert Grassmann)
6*/
7
8
9
10
11#include <misc/auxiliary.h>
12
13#include <factory/factory.h>
14
15#include <coeffs/longrat.h>
16
17
18// 64 bit version:
19#if SIZEOF_LONG == 8
20//#if 0
21#define MAX_NUM_SIZE 60
22#define POW_2_28 (1L<<60)
23#define LONG long
24#else
25#define MAX_NUM_SIZE 28
26#define POW_2_28 (1L<<28)
27#define LONG int
28#endif
29
30static inline number nlShort3(number x) // assume x->s==3
31{
32  assume(x->s==3);
33  if (mpz_cmp_ui(x->z,(long)0)==0)
34  {
35    mpz_clear(x->z);
36    FREE_RNUMBER(x);
37    return INT_TO_SR(0);
38  }
39  if (mpz_size1(x->z)<=MP_SMALL)
40  {
41    LONG ui=mpz_get_si(x->z);
42    if ((((ui<<3)>>3)==ui)
43    && (mpz_cmp_si(x->z,(long)ui)==0))
44    {
45      mpz_clear(x->z);
46      FREE_RNUMBER(x);
47      return INT_TO_SR(ui);
48    }
49  }
50  return x;
51}
52
53#ifndef LONGRAT_CC
54#define LONGRAT_CC
55
56#include <string.h>
57#include <float.h>
58
59#include <coeffs/coeffs.h>
60#include <reporter/reporter.h>
61#include <omalloc/omalloc.h>
62
63#include <coeffs/numbers.h>
64#include <coeffs/modulop.h>
65#include <coeffs/shortfl.h>
66#include <coeffs/mpr_complex.h>
67
68#ifndef BYTES_PER_MP_LIMB
69#define BYTES_PER_MP_LIMB sizeof(mp_limb_t)
70#endif
71
72//#define SR_HDL(A) ((long)(A))
73/*#define SR_INT    1L*/
74/*#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))*/
75// #define SR_TO_INT(SR)   (((long)SR) >> 2)
76
77#define MP_SMALL 1
78//#define mpz_isNeg(A) (mpz_cmp_si(A,(long)0)<0)
79#define mpz_isNeg(A) ((A)->_mp_size<0)
80#define mpz_limb_size(A) ((A)->_mp_size)
81#define mpz_limb_d(A) ((A)->_mp_d)
82#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
83#define MPZ_EXACTDIV(A,B,C) mpz_divexact((A),(B),(C))
84
85/// Our Type!
86static const n_coeffType ID = n_Q;
87
88void    _nlDelete_NoImm(number *a);
89
90/***************************************************************
91 *
92 * Routines which are never inlined by p_Numbers.h
93 *
94 *******************************************************************/
95#ifndef P_NUMBERS_H
96
97number nlShort3_noinline(number x) // assume x->s==3
98{
99  return nlShort3(x);
100}
101
102
103number nlOne=INT_TO_SR(1);
104
105#if (__GNU_MP_VERSION*10+__GNU_MP_VERSION_MINOR < 31)
106void mpz_mul_si (mpz_ptr r, mpz_srcptr s, long int si)
107{
108  if (si>=0)
109    mpz_mul_ui(r,s,si);
110  else
111  {
112    mpz_mul_ui(r,s,-si);
113    mpz_neg(r,r);
114  }
115}
116#endif
117
118static number nlMapP(number from, const coeffs src, const coeffs dst)
119{
120  assume( getCoeffType(dst) == ID );
121  assume( getCoeffType(src) == n_Zp );
122
123  number to;
124  to = nlInit(npInt(from,src), dst);
125  return to;
126}
127
128static number nlMapLongR(number from, const coeffs src, const coeffs dst);
129static number nlMapR(number from, const coeffs src, const coeffs dst);
130
131
132#ifdef HAVE_RINGS
133/*2
134* convert from a GMP integer
135*/
136number nlMapGMP(number from, const coeffs /*src*/, const coeffs /*dst*/)
137{
138  number z=ALLOC_RNUMBER();
139#if defined(LDEBUG)
140  z->debug=123456;
141#endif
142  mpz_init_set(z->z,(mpz_ptr) from);
143  //mpz_init_set_ui(&z->n,1);
144  z->s = 3;
145  z=nlShort3(z);
146  return z;
147}
148
149/*2
150* convert from an machine long
151*/
152number nlMapMachineInt(number from, const coeffs /*src*/, const coeffs /*dst*/)
153{
154  number z=ALLOC_RNUMBER();
155#if defined(LDEBUG)
156  z->debug=123456;
157#endif
158  mpz_init_set_ui(z->z,(unsigned long) from);
159  z->s = 3;
160  z=nlShort3(z);
161  return z;
162}
163#endif
164
165
166#ifdef LDEBUG
167BOOLEAN nlDBTest(number a, const char *f,const int l, const coeffs /*r*/)
168{
169  if (a==NULL)
170  {
171    Print("!!longrat: NULL in %s:%d\n",f,l);
172    return FALSE;
173  }
174  //if ((int)a==1) Print("!! 0x1 as number ? %s %d\n",f,l);
175  if ((((long)a)&3L)==3L)
176  {
177    Print(" !!longrat:ptr(3) in %s:%d\n",f,l);
178    return FALSE;
179  }
180  if ((((long)a)&3L)==1L)
181  {
182    if (((((LONG)(long)a)<<1)>>1)!=((LONG)(long)a))
183    {
184      Print(" !!longrat:arith:%lx in %s:%d\n",(long)a, f,l);
185      return FALSE;
186    }
187    return TRUE;
188  }
189  /* TODO: If next line is active, then computations in algebraic field
190           extensions over Q will throw a lot of assume violations although
191           everything is computed correctly and no seg fault appears.
192           Maybe the test is not appropriate in this case. */
193  omCheckIf(omCheckAddrSize(a,sizeof(*a)), return FALSE);
194  if (a->debug!=123456)
195  {
196    Print("!!longrat:debug:%d in %s:%d\n",a->debug,f,l);
197    a->debug=123456;
198    return FALSE;
199  }
200  if ((a->s<0)||(a->s>4))
201  {
202    Print("!!longrat:s=%d in %s:%d\n",a->s,f,l);
203    return FALSE;
204  }
205  /* TODO: If next line is active, then computations in algebraic field
206           extensions over Q will throw a lot of assume violations although
207           everything is computed correctly and no seg fault appears.
208           Maybe the test is not appropriate in this case. */
209  //omCheckAddrSize(a->z[0]._mp_d,a->z[0]._mp_alloc*BYTES_PER_MP_LIMB);
210  if (a->z[0]._mp_alloc==0)
211    Print("!!longrat:z->alloc=0 in %s:%d\n",f,l);
212
213  if (a->s<2)
214  {
215    if ((a->n[0]._mp_d[0]==0)&&(a->n[0]._mp_alloc<=1))
216    {
217      Print("!!longrat: n==0 in %s:%d\n",f,l);
218      return FALSE;
219    }
220    /* TODO: If next line is active, then computations in algebraic field
221             extensions over Q will throw a lot of assume violations although
222             everything is computed correctly and no seg fault appears.
223             Maybe the test is not appropriate in this case. */
224    //omCheckIf(omCheckAddrSize(a->n[0]._mp_d,a->n[0]._mp_alloc*BYTES_PER_MP_LIMB), return FALSE);
225    if (a->z[0]._mp_alloc==0)
226      Print("!!longrat:n->alloc=0 in %s:%d\n",f,l);
227    if ((mpz_size1(a->n) ==1) && (mpz_cmp_si(a->n,(long)1)==0))
228    {
229      Print("!!longrat:integer as rational in %s:%d\n",f,l);
230      mpz_clear(a->n); a->s=3;
231      return FALSE;
232    }
233    else if (mpz_isNeg(a->n))
234    {
235      Print("!!longrat:div. by negative in %s:%d\n",f,l);
236      mpz_neg(a->z,a->z);
237      mpz_neg(a->n,a->n);
238      return FALSE;
239    }
240    return TRUE;
241  }
242  //if (a->s==2)
243  //{
244  //  Print("!!longrat:s=2 in %s:%d\n",f,l);
245  //  return FALSE;
246  //}
247  if (mpz_size1(a->z)>MP_SMALL) return TRUE;
248  LONG ui=(int)mpz_get_si(a->z);
249  if ((((ui<<3)>>3)==ui)
250  && (mpz_cmp_si(a->z,(long)ui)==0))
251  {
252    Print("!!longrat:im int %d in %s:%d\n",ui,f,l);
253    f=NULL;
254    return FALSE;
255  }
256  return TRUE;
257}
258#endif
259
260CanonicalForm nlConvSingNFactoryN( number n, BOOLEAN setChar, const coeffs /*r*/ )
261{
262  if (setChar) setCharacteristic( 0 );
263
264  CanonicalForm term;
265  if ( SR_HDL(n) & SR_INT )
266  {
267    int nn=SR_TO_INT(n);
268    if ((long)nn==SR_TO_INT(n))
269       term = nn;
270    else
271    {
272        mpz_t dummy;
273        mpz_init_set_si(dummy, SR_TO_INT(n));
274        term = make_cf(dummy);
275    }
276  }
277  else
278  {
279    if ( n->s == 3 )
280    {
281      mpz_t dummy;
282      long lz=mpz_get_si(n->z);
283      if (mpz_cmp_si(n->z,lz)==0) term=lz;
284      else
285      {
286        mpz_init_set( dummy,n->z );
287        term = make_cf( dummy );
288      }
289    }
290    else
291    {
292      // assume s==0 or s==1
293      mpz_t num, den;
294      On(SW_RATIONAL);
295      mpz_init_set( num, n->z );
296      mpz_init_set( den, n->n );
297      term = make_cf( num, den, ( n->s != 1 ));
298    }
299  }
300  return term;
301}
302
303number nlConvFactoryNSingN( const CanonicalForm n, const coeffs r)
304{
305  if (n.isImm())
306  {
307    long lz=n.intval();
308    int iz=(int)lz;
309    if ((long)iz==lz)
310    {
311      return nlInit(n.intval(),r);
312    }
313    else  return nlRInit(lz);
314    return nlInit(n.intval(),r);
315  }
316  else
317  {
318    number z = ALLOC_RNUMBER(); //Q!? // (number)omAllocBin(rnumber_bin);
319#if defined(LDEBUG)
320    z->debug=123456;
321#endif
322    gmp_numerator( n, z->z );
323    if ( n.den().isOne() )
324      z->s = 3;
325    else
326    {
327      gmp_denominator( n, z->n );
328      z->s = 0;
329    }
330    nlNormalize(z,r);
331    return z;
332  }
333}
334
335number nlRInit (long i);
336
337static number nlMapR(number from, const coeffs src, const coeffs dst)
338{
339  assume( getCoeffType(dst) == ID );
340  assume( getCoeffType(src) == n_R );
341
342  double f=nrFloat(from);
343  if (f==0.0) return INT_TO_SR(0);
344  int f_sign=1;
345  if (f<0.0)
346  {
347    f_sign=-1;
348    f=-f;
349  }
350  int i=0;
351  mpz_t h1;
352  mpz_init_set_ui(h1,1);
353  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
354  {
355    f*=FLT_RADIX;
356    mpz_mul_ui(h1,h1,FLT_RADIX);
357    i++;
358  }
359  number re=nlRInit(1);
360  mpz_set_d(re->z,f);
361  memcpy(&(re->n),&h1,sizeof(h1));
362  re->s=0; /* not normalized */
363  if(f_sign==-1) re=nlNeg(re,dst);
364  nlNormalize(re,dst);
365  return re;
366}
367
368static number nlMapLongR(number from, const coeffs src, const coeffs dst)
369{
370  assume( getCoeffType(dst) == ID );
371  assume( getCoeffType(src) == n_long_R );
372
373  gmp_float *ff=(gmp_float*)from;
374  mpf_t *f=ff->_mpfp();
375  number res;
376  mpz_ptr dest,ndest;
377  int size, i,negative;
378  int e,al,bl;
379  mp_ptr qp,dd,nn;
380
381  size = (*f)[0]._mp_size;
382  if (size == 0)
383    return INT_TO_SR(0);
384  if(size<0)
385  {
386    negative = 1;
387    size = -size;
388  }
389  else
390    negative = 0;
391
392  qp = (*f)[0]._mp_d;
393  while(qp[0]==0)
394  {
395    qp++;
396    size--;
397  }
398
399  e=(*f)[0]._mp_exp-size;
400  res = ALLOC_RNUMBER();
401#if defined(LDEBUG)
402  res->debug=123456;
403#endif
404  dest = res->z;
405
406  if (e<0)
407  {
408    al = dest->_mp_size = size;
409    if (al<2) al = 2;
410    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
411    for (i=0;i<size;i++) dd[i] = qp[i];
412    bl = 1-e;
413    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
414    nn[bl-1] = 1;
415    for (i=bl-2;i>=0;i--) nn[i] = 0;
416    ndest = res->n;
417    ndest->_mp_d = nn;
418    ndest->_mp_alloc = ndest->_mp_size = bl;
419    res->s = 0;
420  }
421  else
422  {
423    al = dest->_mp_size = size+e;
424    if (al<2) al = 2;
425    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
426    for (i=0;i<size;i++) dd[i+e] = qp[i];
427    for (i=0;i<e;i++) dd[i] = 0;
428    res->s = 3;
429  }
430
431  dest->_mp_d = dd;
432  dest->_mp_alloc = al;
433  if (negative) dest->_mp_size = -dest->_mp_size;
434
435  if (res->s==0)
436    nlNormalize(res,dst);
437  else if (mpz_size1(res->z)<=MP_SMALL)
438  {
439    // res is new, res->ref is 1
440    res=nlShort3(res);
441  }
442  nlTest(res, dst);
443  return res;
444}
445
446//static number nlMapLongR(number from)
447//{
448//  gmp_float *ff=(gmp_float*)from;
449//  const mpf_t *f=ff->mpfp();
450//  int f_size=ABS((*f)[0]._mp_size);
451//  if (f_size==0)
452//    return nlInit(0);
453//  int f_sign=1;
454//  number work=ngcCopy(from);
455//  if (!ngcGreaterZero(work))
456//  {
457//    f_sign=-1;
458//    work=ngcNeg(work);
459//  }
460//  int i=0;
461//  mpz_t h1;
462//  mpz_init_set_ui(h1,1);
463//  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
464//  {
465//    f*=FLT_RADIX;
466//    mpz_mul_ui(h1,h1,FLT_RADIX);
467//    i++;
468//  }
469//  number r=nlRInit(1);
470//  mpz_set_d(&(r->z),f);
471//  memcpy(&(r->n),&h1,sizeof(h1));
472//  r->s=0; /* not normalized */
473//  nlNormalize(r);
474//  return r;
475//
476//
477//  number r=nlRInit(1);
478//  int f_shift=f_size+(*f)[0]._mp_exp;
479//  if ( f_shift > 0)
480//  {
481//    r->s=0;
482//    mpz_init(&r->n);
483//    mpz_setbit(&r->n,f_shift*BYTES_PER_MP_LIMB*8);
484//    mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
485//    // now r->z has enough space
486//    memcpy(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
487//    nlNormalize(r);
488//  }
489//  else
490//  {
491//    r->s=3;
492//    if (f_shift==0)
493//    {
494//      mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
495//      // now r->z has enough space
496//      memcpy(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
497//    }
498//    else /* f_shift < 0 */
499//    {
500//      mpz_setbit(&r->z,(f_size-f_shift)*BYTES_PER_MP_LIMB*8-1);
501//      // now r->z has enough space
502//      memcpy(mpz_limb_d(&r->z)-f_shift,((*f)[0]._mp_d),
503//        f_size*BYTES_PER_MP_LIMB);
504//    }
505//  }
506//  if ((*f)[0]._mp_size<0);
507//    r=nlNeg(r);
508//  return r;
509//}
510
511int nlSize(number a, const coeffs)
512{
513  if (a==INT_TO_SR(0))
514     return 0; /* rational 0*/
515  if (SR_HDL(a) & SR_INT)
516     return 1; /* immidiate int */
517  int s=a->z[0]._mp_alloc;
518//  while ((s>0) &&(a->z._mp_d[s]==0L)) s--;
519//#if SIZEOF_LONG == 8
520//  if (a->z._mp_d[s] < (unsigned long)0x100000000L) s=s*2-1;
521//  else s *=2;
522//#endif
523//  s++;
524  if (a->s<2)
525  {
526    int d=a->n[0]._mp_alloc;
527//    while ((d>0) && (a->n._mp_d[d]==0L)) d--;
528//#if SIZEOF_LONG == 8
529//    if (a->n._mp_d[d] < (unsigned long)0x100000000L) d=d*2-1;
530//    else d *=2;
531//#endif
532    s+=d;
533  }
534  return s;
535}
536
537/*2
538* convert number to int
539*/
540int nlInt(number &i, const coeffs r)
541{
542  nlTest(i, r);
543  nlNormalize(i,r);
544  if (SR_HDL(i) & SR_INT)
545  {
546    int dummy = SR_TO_INT(i);
547    if((long)dummy == SR_TO_INT(i))
548        return SR_TO_INT(i);
549    else
550        return 0;
551  }
552  if (i->s==3)
553  {
554    if(mpz_size1(i->z)>MP_SMALL) return 0;
555    int ul=(int)mpz_get_si(i->z);
556    if (mpz_cmp_si(i->z,(long)ul)!=0) return 0;
557    return ul;
558  }
559  mpz_t tmp;
560  int ul;
561  mpz_init(tmp);
562  MPZ_DIV(tmp,i->z,i->n);
563  if(mpz_size1(tmp)>MP_SMALL) ul=0;
564  else
565  {
566    ul=(int)mpz_get_si(tmp);
567    if (mpz_cmp_si(tmp,(long)ul)!=0) ul=0;
568  }
569  mpz_clear(tmp);
570  return ul;
571}
572
573/*2
574* convert number to bigint
575*/
576number nlBigInt(number &i, const coeffs r)
577{
578  nlTest(i, r);
579  nlNormalize(i,r);
580  if (SR_HDL(i) & SR_INT) return (i);
581  if (i->s==3)
582  {
583    return nlCopy(i,r);
584  }
585  number tmp=nlRInit(1);
586  MPZ_DIV(tmp->z,i->z,i->n);
587  tmp=nlShort3(tmp);
588  return tmp;
589}
590
591/*
592* 1/a
593*/
594number nlInvers(number a, const coeffs r)
595{
596  nlTest(a, r);
597  number n;
598  if (SR_HDL(a) & SR_INT)
599  {
600    if ((a==INT_TO_SR(1L)) || (a==INT_TO_SR(-1L)))
601    {
602      return a;
603    }
604    if (nlIsZero(a,r))
605    {
606      WerrorS(nDivBy0);
607      return INT_TO_SR(0);
608    }
609    n=ALLOC_RNUMBER();
610#if defined(LDEBUG)
611    n->debug=123456;
612#endif
613    n->s=1;
614    if ((long)a>0L)
615    {
616      mpz_init_set_si(n->z,(long)1);
617      mpz_init_set_si(n->n,(long)SR_TO_INT(a));
618    }
619    else
620    {
621      mpz_init_set_si(n->z,(long)-1);
622      mpz_init_set_si(n->n,(long)-SR_TO_INT(a));
623    }
624    nlTest(n, r);
625    return n;
626  }
627  n=ALLOC_RNUMBER();
628#if defined(LDEBUG)
629  n->debug=123456;
630#endif
631  {
632    n->s=a->s;
633    mpz_init_set(n->n,a->z);
634    switch (a->s)
635    {
636      case 0:
637      case 1:
638              mpz_init_set(n->z,a->n);
639              if (mpz_isNeg(n->n)) /* && n->s<2*/
640              {
641                mpz_neg(n->z,n->z);
642                mpz_neg(n->n,n->n);
643              }
644              if (mpz_cmp_si(n->n,(long)1)==0)
645              {
646                mpz_clear(n->n);
647                n->s=3;
648                n=nlShort3(n);
649              }
650              break;
651      case 3:
652              n->s=1;
653              if (mpz_isNeg(n->n)) /* && n->s<2*/
654              {
655                mpz_neg(n->n,n->n);
656                mpz_init_set_si(n->z,(long)-1);
657              }
658              else
659              {
660                mpz_init_set_si(n->z,(long)1);
661              }
662              break;
663    }
664  }
665  nlTest(n, r);
666  return n;
667}
668
669
670/*2
671* u := a / b in Z, if b | a (else undefined)
672*/
673number   nlExactDiv(number a, number b, const coeffs r)
674{
675  if (b==INT_TO_SR(0))
676  {
677    WerrorS(nDivBy0);
678    return INT_TO_SR(0);
679  }
680  if (a==INT_TO_SR(0))
681    return INT_TO_SR(0);
682  number u;
683  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
684  {
685    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
686    if ((a==INT_TO_SR(-(POW_2_28)))&&(b==INT_TO_SR(-1L)))
687    {
688      return nlRInit(POW_2_28);
689    }
690    long aa=SR_TO_INT(a);
691    long bb=SR_TO_INT(b);
692    return INT_TO_SR(aa/bb);
693  }
694  number bb=NULL;
695  if (SR_HDL(b) & SR_INT)
696  {
697    bb=nlRInit(SR_TO_INT(b));
698    b=bb;
699  }
700  u=ALLOC_RNUMBER();
701#if defined(LDEBUG)
702  u->debug=123456;
703#endif
704  mpz_init(u->z);
705  /* u=a/b */
706  u->s = 3;
707  MPZ_EXACTDIV(u->z,a->z,b->z);
708  if (bb!=NULL)
709  {
710    mpz_clear(bb->z);
711#if defined(LDEBUG)
712    bb->debug=654324;
713#endif
714    FREE_RNUMBER(bb); // omFreeBin((void *)bb, rnumber_bin);
715  }
716  u=nlShort3(u);
717  nlTest(u, r);
718  return u;
719}
720
721/*2
722* u := a / b in Z
723*/
724number nlIntDiv (number a, number b, const coeffs r)
725{
726  if (b==INT_TO_SR(0))
727  {
728    WerrorS(nDivBy0);
729    return INT_TO_SR(0);
730  }
731  if (a==INT_TO_SR(0))
732    return INT_TO_SR(0);
733  number u;
734  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
735  {
736    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
737    if ((a==INT_TO_SR(-(POW_2_28)))&&(b==INT_TO_SR(-1L)))
738    {
739      return nlRInit(POW_2_28);
740    }
741    long aa=SR_TO_INT(a);
742    long bb=SR_TO_INT(b);
743    return INT_TO_SR(aa/bb);
744  }
745  if (SR_HDL(a) & SR_INT)
746  {
747    /* the small int -(1<<28) divided by 2^28 is 1   */
748    if (a==INT_TO_SR(-(POW_2_28)))
749    {
750      if(mpz_cmp_si(b->z,(POW_2_28))==0)
751      {
752        return INT_TO_SR(-1);
753      }
754    }
755    /* a is a small and b is a large int: -> 0 */
756    return INT_TO_SR(0);
757  }
758  number bb=NULL;
759  if (SR_HDL(b) & SR_INT)
760  {
761    bb=nlRInit(SR_TO_INT(b));
762    b=bb;
763  }
764  u=ALLOC_RNUMBER();
765#if defined(LDEBUG)
766  u->debug=123456;
767#endif
768  assume(a->s==3);
769  assume(b->s==3);
770  mpz_init_set(u->z,a->z);
771  /* u=u/b */
772  u->s = 3;
773  MPZ_DIV(u->z,u->z,b->z);
774  if (bb!=NULL)
775  {
776    mpz_clear(bb->z);
777#if defined(LDEBUG)
778    bb->debug=654324;
779#endif
780    FREE_RNUMBER(bb);
781  }
782  u=nlShort3(u);
783  nlTest(u,r);
784  return u;
785}
786
787/*2
788* u := a mod b in Z, u>=0
789*/
790number nlIntMod (number a, number b, const coeffs r)
791{
792  if (b==INT_TO_SR(0))
793  {
794    WerrorS(nDivBy0);
795    return INT_TO_SR(0);
796  }
797  if (a==INT_TO_SR(0))
798    return INT_TO_SR(0);
799  number u;
800  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
801  {
802    LONG bb=SR_TO_INT(b);
803    LONG c=SR_TO_INT(a) % bb;
804    /*if(c < 0)
805    {
806        if(bb < 0)
807            c = c - bb;
808        else
809            c = c + bb;
810    }*/
811    /*if((((SR_TO_INT(a)) / (bb))*bb+c) != SR_TO_INT(a))
812    {
813        printf("\nERROR longrat:819\n");
814        printf("\na = %ld\n",SR_TO_INT(a));
815        printf("\nb = %ld\n",bb);
816        printf("\nc = %ld\n",c);
817    }*/
818    return INT_TO_SR(c);
819  }
820  if (SR_HDL(a) & SR_INT)
821  {
822    // a is a small and b is a large int: -> a
823    //  INCORRECT, IT COULD HAPPEN THAT b IS A SMALL NUMBER
824    number aa=ALLOC_RNUMBER();
825    mpz_init(aa->z);
826    mpz_set_si(aa->z, SR_TO_INT(a));
827    u=ALLOC_RNUMBER();
828#if defined(LDEBUG)
829    u->debug=123456;
830#endif
831    u->s = 3;
832    mpz_init(u->z);
833    mpz_mod(u->z,aa->z,b->z);
834    if (mpz_isNeg(u->z))
835    {
836      if (mpz_isNeg(b->z))
837        mpz_sub(u->z,aa->z,b->z);
838      else
839        mpz_add(u->z,aa->z,b->z);
840    }
841    /*mpz_t dummy;
842    mpz_init(dummy);
843    mpz_fdiv_q(dummy, aa->z, b->z);
844    mpz_mul(dummy, dummy, b->z);
845    mpz_add(dummy, dummy, u->z);
846    if(mpz_cmp(dummy,aa->z) != 0)
847    {
848        printf("\nERROR longrat:911\n");
849        printf("\na = ");n_Print(aa,r);
850        gmp_printf("\ndummy = %Zd",dummy);
851        mpz_clear(dummy);mpz_init(dummy);mpz_tdiv_q(dummy, a->z, b->z);
852        gmp_printf("\na div b = %Zd\n u = ", dummy);
853        n_Print(u,r);
854    }
855    mpz_clear(dummy);*/
856    mpz_clear(aa->z);
857    #if defined(LDEBUG)
858    aa->debug=654324;
859    #endif
860    FREE_RNUMBER(aa);
861    u=nlShort3(u);
862    nlTest(u,r);
863    return u;
864  }
865  number bb=NULL;
866  if (SR_HDL(b) & SR_INT)
867  {
868    bb=nlRInit(SR_TO_INT(b));
869    b=bb;
870  }
871  u=ALLOC_RNUMBER();
872#if defined(LDEBUG)
873  u->debug=123456;
874#endif
875  mpz_init(u->z);
876  u->s = 3;
877  mpz_mod(u->z,a->z,b->z);
878  if (mpz_isNeg(u->z))
879  {
880    if (mpz_isNeg(b->z))
881      mpz_sub(u->z,u->z,b->z);
882    else
883      mpz_add(u->z,u->z,b->z);
884  }
885  if (bb!=NULL)
886  {
887    mpz_clear(bb->z);
888#if defined(LDEBUG)
889    bb->debug=654324;
890#endif
891    FREE_RNUMBER(bb);
892  }
893  /*mpz_t dummy;
894  mpz_init(dummy);
895    mpz_fdiv_q(dummy, a->z, b->z);
896    mpz_mul(dummy, dummy, b->z);
897    mpz_add(dummy, dummy, u->z);
898    if(mpz_cmp(dummy,a->z) != 0)
899    {
900        printf("\nERROR longrat:911\n");
901        printf("\na = ");n_Print(a,r);
902        gmp_printf("\ndummy = %Zd",dummy);
903        mpz_clear(dummy);mpz_init(dummy);mpz_tdiv_q(dummy, a->z, b->z);
904        gmp_printf("\na div b = %Zd\n u = ", dummy);
905        n_Print(u,r);
906    }
907    mpz_clear(dummy);*/
908  u=nlShort3(u);
909  nlTest(u,r);
910  return u;
911}
912
913/*2
914* u := a / b
915*/
916number nlDiv (number a, number b, const coeffs r)
917{
918  if (nlIsZero(b,r))
919  {
920    WerrorS(nDivBy0);
921    return INT_TO_SR(0);
922  }
923  number u;
924// ---------- short / short ------------------------------------
925  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
926  {
927    LONG i=SR_TO_INT(a);
928    LONG j=SR_TO_INT(b);
929    if (j==1L) return a;
930    if ((i==-POW_2_28) && (j== -1L))
931    {
932      return nlRInit(POW_2_28);
933    }
934    LONG r=i%j;
935    if (r==0)
936    {
937      return INT_TO_SR(i/j);
938    }
939    u=ALLOC_RNUMBER();
940    u->s=0;
941    #if defined(LDEBUG)
942    u->debug=123456;
943    #endif
944    mpz_init_set_si(u->z,(long)i);
945    mpz_init_set_si(u->n,(long)j);
946  }
947  else
948  {
949    u=ALLOC_RNUMBER();
950    u->s=0;
951    #if defined(LDEBUG)
952    u->debug=123456;
953    #endif
954    mpz_init(u->z);
955// ---------- short / long ------------------------------------
956    if (SR_HDL(a) & SR_INT)
957    {
958      // short a / (z/n) -> (a*n)/z
959      if (b->s<2)
960      {
961        mpz_mul_si(u->z,b->n,SR_TO_INT(a));
962      }
963      else
964      // short a / long z -> a/z
965      {
966        mpz_set_si(u->z,SR_TO_INT(a));
967      }
968      if (mpz_cmp(u->z,b->z)==0)
969      {
970        mpz_clear(u->z);
971        FREE_RNUMBER(u);
972        return INT_TO_SR(1);
973      }
974      mpz_init_set(u->n,b->z);
975    }
976// ---------- long / short ------------------------------------
977    else if (SR_HDL(b) & SR_INT)
978    {
979      mpz_set(u->z,a->z);
980      // (z/n) / b -> z/(n*b)
981      if (a->s<2)
982      {
983        mpz_init_set(u->n,a->n);
984        if ((long)b>0L)
985          mpz_mul_ui(u->n,u->n,SR_TO_INT(b));
986        else
987        {
988          mpz_mul_ui(u->n,u->n,-SR_TO_INT(b));
989          mpz_neg(u->z,u->z);
990        }
991      }
992      else
993      // long z / short b -> z/b
994      {
995        //mpz_set(u->z,a->z);
996        mpz_init_set_si(u->n,SR_TO_INT(b));
997      }
998    }
999// ---------- long / long ------------------------------------
1000    else
1001    {
1002      mpz_set(u->z,a->z);
1003      mpz_init_set(u->n,b->z);
1004      if (a->s<2) mpz_mul(u->n,u->n,a->n);
1005      if (b->s<2) mpz_mul(u->z,u->z,b->n);
1006    }
1007  }
1008  if (mpz_isNeg(u->n))
1009  {
1010    mpz_neg(u->z,u->z);
1011    mpz_neg(u->n,u->n);
1012  }
1013  if (mpz_cmp_si(u->n,(long)1)==0)
1014  {
1015    mpz_clear(u->n);
1016    u->s=3;
1017    u=nlShort3(u);
1018  }
1019  nlTest(u, r);
1020  return u;
1021}
1022
1023/*2
1024* u:= x ^ exp
1025*/
1026void nlPower (number x,int exp,number * u, const coeffs r)
1027{
1028  *u = INT_TO_SR(0); // 0^e, e!=0
1029  if (exp==0)
1030    *u= INT_TO_SR(1);
1031  else if (!nlIsZero(x,r))
1032  {
1033    nlTest(x, r);
1034    number aa=NULL;
1035    if (SR_HDL(x) & SR_INT)
1036    {
1037      aa=nlRInit(SR_TO_INT(x));
1038      x=aa;
1039    }
1040    else if (x->s==0)
1041      nlNormalize(x,r);
1042    *u=ALLOC_RNUMBER();
1043#if defined(LDEBUG)
1044    (*u)->debug=123456;
1045#endif
1046    mpz_init((*u)->z);
1047    mpz_pow_ui((*u)->z,x->z,(unsigned long)exp);
1048    if (x->s<2)
1049    {
1050      if (mpz_cmp_si(x->n,(long)1)==0)
1051      {
1052        x->s=3;
1053        mpz_clear(x->n);
1054      }
1055      else
1056      {
1057        mpz_init((*u)->n);
1058        mpz_pow_ui((*u)->n,x->n,(unsigned long)exp);
1059      }
1060    }
1061    (*u)->s = x->s;
1062    if ((*u)->s==3) *u=nlShort3(*u);
1063    if (aa!=NULL)
1064    {
1065      mpz_clear(aa->z);
1066      FREE_RNUMBER(aa);
1067    }
1068  }
1069#ifdef LDEBUG
1070  if (exp<0) Print("nlPower: neg. exp. %d\n",exp);
1071  nlTest(*u, r);
1072#endif
1073}
1074
1075
1076/*2
1077* za >= 0 ?
1078*/
1079BOOLEAN nlGreaterZero (number a, const coeffs r)
1080{
1081  nlTest(a, r);
1082  if (SR_HDL(a) & SR_INT) return SR_HDL(a)>1L /* represents number(0) */;
1083  return (!mpz_isNeg(a->z));
1084}
1085
1086/*2
1087* a > b ?
1088*/
1089BOOLEAN nlGreater (number a, number b, const coeffs r)
1090{
1091  nlTest(a, r);
1092  nlTest(b, r);
1093  number re;
1094  BOOLEAN rr;
1095  re=nlSub(a,b,r);
1096  rr=(!nlIsZero(re,r)) && (nlGreaterZero(re,r));
1097  nlDelete(&re,r);
1098  return rr;
1099}
1100
1101/*2
1102* a == -1 ?
1103*/
1104BOOLEAN nlIsMOne (number a, const coeffs r)
1105{
1106#ifdef LDEBUG
1107  if (a==NULL) return FALSE;
1108  nlTest(a, r);
1109#endif
1110  //if (SR_HDL(a) & SR_INT) return (a==INT_TO_SR(-1L));
1111  //return FALSE;
1112  return  (a==INT_TO_SR(-1L));
1113}
1114
1115/*2
1116* result =gcd(a,b)
1117*/
1118number nlGcd(number a, number b, const coeffs r)
1119{
1120  number result;
1121  nlTest(a, r);
1122  nlTest(b, r);
1123  //nlNormalize(a);
1124  //nlNormalize(b);
1125  if ((a==INT_TO_SR(1L))||(a==INT_TO_SR(-1L))
1126  ||  (b==INT_TO_SR(1L))||(b==INT_TO_SR(-1L)))
1127    return INT_TO_SR(1L);
1128  if (a==INT_TO_SR(0)) /* gcd(0,b) ->b */
1129    return nlCopy(b,r);
1130  if (b==INT_TO_SR(0)) /* gcd(a,0) -> a */
1131    return nlCopy(a,r);
1132  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
1133  {
1134    long i=SR_TO_INT(a);
1135    long j=SR_TO_INT(b);
1136    if((i==0L)||(j==0L))
1137      return INT_TO_SR(1);
1138    long l;
1139    i=ABS(i);
1140    j=ABS(j);
1141    do
1142    {
1143      l=i%j;
1144      i=j;
1145      j=l;
1146    } while (l!=0L);
1147    if (i==POW_2_28)
1148      result=nlRInit(POW_2_28);
1149    else
1150     result=INT_TO_SR(i);
1151    nlTest(result,r);
1152    return result;
1153  }
1154  if (((!(SR_HDL(a) & SR_INT))&&(a->s<2))
1155  ||  ((!(SR_HDL(b) & SR_INT))&&(b->s<2))) return INT_TO_SR(1);
1156  if (SR_HDL(a) & SR_INT)
1157  {
1158    LONG aa=ABS(SR_TO_INT(a));
1159    unsigned long t=mpz_gcd_ui(NULL,b->z,(long)aa);
1160    if (t==POW_2_28)
1161      result=nlRInit(POW_2_28);
1162    else
1163     result=INT_TO_SR(t);
1164  }
1165  else
1166  if (SR_HDL(b) & SR_INT)
1167  {
1168    LONG bb=ABS(SR_TO_INT(b));
1169    unsigned long t=mpz_gcd_ui(NULL,a->z,(long)bb);
1170    if (t==POW_2_28)
1171      result=nlRInit(POW_2_28);
1172    else
1173     result=INT_TO_SR(t);
1174  }
1175  else
1176  {
1177    result=ALLOC0_RNUMBER();
1178    mpz_init(result->z);
1179    mpz_gcd(result->z,a->z,b->z);
1180    result->s = 3;
1181  #ifdef LDEBUG
1182    result->debug=123456;
1183  #endif
1184    result=nlShort3(result);
1185  }
1186  nlTest(result, r);
1187  return result;
1188}
1189
1190number nlShort1(number x) // assume x->s==0/1
1191{
1192  assume(x->s<2);
1193  if (mpz_cmp_ui(x->z,(long)0)==0)
1194  {
1195    _nlDelete_NoImm(&x);
1196    return INT_TO_SR(0);
1197  }
1198  if (x->s<2)
1199  {
1200    if (mpz_cmp(x->z,x->n)==0)
1201    {
1202      _nlDelete_NoImm(&x);
1203      return INT_TO_SR(1);
1204    }
1205  }
1206  return x;
1207}
1208/*2
1209* simplify x
1210*/
1211void nlNormalize (number &x, const coeffs r)
1212{
1213  if ((SR_HDL(x) & SR_INT) ||(x==NULL))
1214    return;
1215  if (x->s==3)
1216  {
1217    x=nlShort3_noinline(x);
1218    nlTest(x,r);
1219    return;
1220  }
1221  else if (x->s==0)
1222  {
1223    if (mpz_cmp_si(x->n,(long)1)==0)
1224    {
1225      mpz_clear(x->n);
1226      x->s=3;
1227      x=nlShort3(x);
1228    }
1229    else
1230    {
1231      mpz_t gcd;
1232      mpz_init(gcd);
1233      mpz_gcd(gcd,x->z,x->n);
1234      x->s=1;
1235      if (mpz_cmp_si(gcd,(long)1)!=0)
1236      {
1237        MPZ_EXACTDIV(x->z,x->z,gcd);
1238        MPZ_EXACTDIV(x->n,x->n,gcd);
1239        if (mpz_cmp_si(x->n,(long)1)==0)
1240        {
1241          mpz_clear(x->n);
1242          x->s=3;
1243          x=nlShort3_noinline(x);
1244        }
1245      }
1246      mpz_clear(gcd);
1247    }
1248  }
1249  nlTest(x, r);
1250}
1251
1252/*2
1253* returns in result->z the lcm(a->z,b->n)
1254*/
1255number nlLcm(number a, number b, const coeffs r)
1256{
1257  number result;
1258  nlTest(a, r);
1259  nlTest(b, r);
1260  if ((SR_HDL(b) & SR_INT)
1261  || (b->s==3))
1262  {
1263    // b is 1/(b->n) => b->n is 1 => result is a
1264    return nlCopy(a,r);
1265  }
1266  result=ALLOC_RNUMBER();
1267#if defined(LDEBUG)
1268  result->debug=123456;
1269#endif
1270  result->s=3;
1271  mpz_t gcd;
1272  mpz_init(gcd);
1273  mpz_init(result->z);
1274  if (SR_HDL(a) & SR_INT)
1275    mpz_gcd_ui(gcd,b->n,ABS(SR_TO_INT(a)));
1276  else
1277    mpz_gcd(gcd,a->z,b->n);
1278  if (mpz_cmp_si(gcd,(long)1)!=0)
1279  {
1280    mpz_t bt;
1281    mpz_init_set(bt,b->n);
1282    MPZ_EXACTDIV(bt,bt,gcd);
1283    if (SR_HDL(a) & SR_INT)
1284      mpz_mul_si(result->z,bt,SR_TO_INT(a));
1285    else
1286      mpz_mul(result->z,bt,a->z);
1287    mpz_clear(bt);
1288  }
1289  else
1290    if (SR_HDL(a) & SR_INT)
1291      mpz_mul_si(result->z,b->n,SR_TO_INT(a));
1292    else
1293      mpz_mul(result->z,b->n,a->z);
1294  mpz_clear(gcd);
1295  result=nlShort3(result);
1296  nlTest(result, r);
1297  return result;
1298}
1299
1300// Map q \in QQ \to Zp
1301// src = Q, dst = Zp (or an extension of Zp?)
1302number nlModP(number q, const coeffs Q, const coeffs Zp)
1303{
1304  assume( getCoeffType(Q) == ID );
1305
1306  const int p = n_GetChar(Zp);
1307  assume( p > 0 );
1308
1309  const long P = p;
1310  assume( P > 0 );
1311
1312  // embedded long within q => only long numerator has to be converted
1313  // to int (modulo char.)
1314  if (SR_HDL(q) & SR_INT)
1315  {
1316    long i = SR_TO_INT(q);
1317    if (i<0L)
1318      return n_Init( static_cast<int>( P - ((-i)%P) ), Zp);
1319    else
1320      return n_Init( static_cast<int>( i % P ), Zp );
1321  }
1322
1323  const unsigned long PP = p;
1324
1325  // numerator modulo char. should fit into int
1326  number z = n_Init( static_cast<int>(mpz_fdiv_ui(q->z, PP)), Zp );
1327
1328  // denominator != 1?
1329  if (q->s!=3)
1330  {
1331    // denominator modulo char. should fit into int
1332    number n = n_Init( static_cast<int>(mpz_fdiv_ui(q->n, PP)), Zp );
1333
1334    number res = n_Div( z, n, Zp );
1335
1336    n_Delete(&z, Zp);
1337    n_Delete(&n, Zp);
1338
1339    return res;
1340  }
1341
1342  return z;
1343}
1344
1345#ifdef HAVE_RINGS
1346/*2
1347* convert number i (from Q) to GMP and warn if denom != 1
1348*/
1349void nlGMP(number &i, number n, const coeffs r)
1350{
1351  // Hier brauche ich einfach die GMP Zahl
1352  nlTest(i, r);
1353  nlNormalize(i, r);
1354  if (SR_HDL(i) & SR_INT)
1355  {
1356    mpz_set_si((mpz_ptr) n, SR_TO_INT(i));
1357    return;
1358  }
1359  if (i->s!=3)
1360  {
1361     WarnS("Omitted denominator during coefficient mapping !");
1362  }
1363  mpz_set((mpz_ptr) n, i->z);
1364}
1365#endif
1366
1367/*2
1368* acces to denominator, other 1 for integers
1369*/
1370number   nlGetDenom(number &n, const coeffs r)
1371{
1372  if (!(SR_HDL(n) & SR_INT))
1373  {
1374    if (n->s==0)
1375    {
1376      nlNormalize(n,r);
1377    }
1378    if (!(SR_HDL(n) & SR_INT))
1379    {
1380      if (n->s!=3)
1381      {
1382        number u=ALLOC_RNUMBER();
1383        u->s=3;
1384#if defined(LDEBUG)
1385        u->debug=123456;
1386#endif
1387        mpz_init_set(u->z,n->n);
1388        u=nlShort3_noinline(u);
1389        return u;
1390      }
1391    }
1392  }
1393  return INT_TO_SR(1);
1394}
1395
1396/*2
1397* acces to Nominator, nlCopy(n) for integers
1398*/
1399number   nlGetNumerator(number &n, const coeffs r)
1400{
1401  if (!(SR_HDL(n) & SR_INT))
1402  {
1403    if (n->s==0)
1404    {
1405      nlNormalize(n,r);
1406    }
1407    if (!(SR_HDL(n) & SR_INT))
1408    {
1409      number u=ALLOC_RNUMBER();
1410#if defined(LDEBUG)
1411      u->debug=123456;
1412#endif
1413      u->s=3;
1414      mpz_init_set(u->z,n->z);
1415      if (n->s!=3)
1416      {
1417        u=nlShort3_noinline(u);
1418      }
1419      return u;
1420    }
1421  }
1422  return n; // imm. int
1423}
1424
1425/***************************************************************
1426 *
1427 * routines which are needed by Inline(d) routines
1428 *
1429 *******************************************************************/
1430BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b)
1431{
1432  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
1433//  long - short
1434  BOOLEAN bo;
1435  if (SR_HDL(b) & SR_INT)
1436  {
1437    if (a->s!=0) return FALSE;
1438    number n=b; b=a; a=n;
1439  }
1440//  short - long
1441  if (SR_HDL(a) & SR_INT)
1442  {
1443    if (b->s!=0)
1444      return FALSE;
1445    if (((long)a > 0L) && (mpz_isNeg(b->z)))
1446      return FALSE;
1447    if (((long)a < 0L) && (!mpz_isNeg(b->z)))
1448      return FALSE;
1449    mpz_t  bb;
1450    mpz_init_set(bb,b->n);
1451    mpz_mul_si(bb,bb,(long)SR_TO_INT(a));
1452    bo=(mpz_cmp(bb,b->z)==0);
1453    mpz_clear(bb);
1454    return bo;
1455  }
1456// long - long
1457  if (((a->s==1) && (b->s==3))
1458  ||  ((b->s==1) && (a->s==3)))
1459    return FALSE;
1460  if (mpz_isNeg(a->z)&&(!mpz_isNeg(b->z)))
1461    return FALSE;
1462  if (mpz_isNeg(b->z)&&(!mpz_isNeg(a->z)))
1463    return FALSE;
1464  mpz_t  aa;
1465  mpz_t  bb;
1466  mpz_init_set(aa,a->z);
1467  mpz_init_set(bb,b->z);
1468  if (a->s<2) mpz_mul(bb,bb,a->n);
1469  if (b->s<2) mpz_mul(aa,aa,b->n);
1470  bo=(mpz_cmp(aa,bb)==0);
1471  mpz_clear(aa);
1472  mpz_clear(bb);
1473  return bo;
1474}
1475
1476// copy not immediate number a
1477number _nlCopy_NoImm(number a)
1478{
1479  assume(!((SR_HDL(a) & SR_INT)||(a==NULL)));
1480  //nlTest(a, r);
1481  number b=ALLOC_RNUMBER();
1482#if defined(LDEBUG)
1483  b->debug=123456;
1484#endif
1485  switch (a->s)
1486  {
1487    case 0:
1488    case 1:
1489            mpz_init_set(b->n,a->n);
1490    case 3:
1491            mpz_init_set(b->z,a->z);
1492            break;
1493  }
1494  b->s = a->s;
1495  return b;
1496}
1497
1498void _nlDelete_NoImm(number *a)
1499{
1500  {
1501    switch ((*a)->s)
1502    {
1503      case 0:
1504      case 1:
1505        mpz_clear((*a)->n);
1506      case 3:
1507        mpz_clear((*a)->z);
1508#ifdef LDEBUG
1509        (*a)->s=2;
1510#endif
1511    }
1512    FREE_RNUMBER(*a); // omFreeBin((void *) *a, rnumber_bin);
1513  }
1514}
1515
1516number _nlNeg_NoImm(number a)
1517{
1518  {
1519    mpz_neg(a->z,a->z);
1520    if (a->s==3)
1521    {
1522      a=nlShort3(a);
1523    }
1524  }
1525  return a;
1526}
1527
1528number _nlAdd_aNoImm_OR_bNoImm(number a, number b)
1529{
1530  number u=ALLOC_RNUMBER();
1531#if defined(LDEBUG)
1532  u->debug=123456;
1533#endif
1534  mpz_init(u->z);
1535  if (SR_HDL(b) & SR_INT)
1536  {
1537    number x=a;
1538    a=b;
1539    b=x;
1540  }
1541  if (SR_HDL(a) & SR_INT)
1542  {
1543    switch (b->s)
1544    {
1545      case 0:
1546      case 1:/* a:short, b:1 */
1547      {
1548        mpz_t x;
1549        mpz_init(x);
1550        mpz_mul_si(x,b->n,SR_TO_INT(a));
1551        mpz_add(u->z,b->z,x);
1552        mpz_clear(x);
1553        if (mpz_cmp_ui(u->z,(long)0)==0)
1554        {
1555          mpz_clear(u->z);
1556          FREE_RNUMBER(u);
1557          return INT_TO_SR(0);
1558        }
1559        if (mpz_cmp(u->z,b->n)==0)
1560        {
1561          mpz_clear(u->z);
1562          FREE_RNUMBER(u);
1563          return INT_TO_SR(1);
1564        }
1565        mpz_init_set(u->n,b->n);
1566        u->s = 0;
1567        break;
1568      }
1569      case 3:
1570      {
1571        if ((long)a>0L)
1572          mpz_add_ui(u->z,b->z,SR_TO_INT(a));
1573        else
1574          mpz_sub_ui(u->z,b->z,-SR_TO_INT(a));
1575        if (mpz_cmp_ui(u->z,(long)0)==0)
1576        {
1577          mpz_clear(u->z);
1578          FREE_RNUMBER(u);
1579          return INT_TO_SR(0);
1580        }
1581        u->s = 3;
1582        u=nlShort3(u);
1583        break;
1584      }
1585    }
1586  }
1587  else
1588  {
1589    switch (a->s)
1590    {
1591      case 0:
1592      case 1:
1593      {
1594        switch(b->s)
1595        {
1596          case 0:
1597          case 1:
1598          {
1599            mpz_t x;
1600            mpz_init(x);
1601
1602            mpz_mul(x,b->z,a->n);
1603            mpz_mul(u->z,a->z,b->n);
1604            mpz_add(u->z,u->z,x);
1605            mpz_clear(x);
1606
1607            if (mpz_cmp_ui(u->z,(long)0)==0)
1608            {
1609              mpz_clear(u->z);
1610              FREE_RNUMBER(u);
1611              return INT_TO_SR(0);
1612            }
1613            mpz_init(u->n);
1614            mpz_mul(u->n,a->n,b->n);
1615            if (mpz_cmp(u->z,u->n)==0)
1616            {
1617               mpz_clear(u->z);
1618               mpz_clear(u->n);
1619               FREE_RNUMBER(u);
1620               return INT_TO_SR(1);
1621            }
1622            u->s = 0;
1623            break;
1624          }
1625          case 3: /* a:1 b:3 */
1626          {
1627            mpz_mul(u->z,b->z,a->n);
1628            mpz_add(u->z,u->z,a->z);
1629            if (mpz_cmp_ui(u->z,(long)0)==0)
1630            {
1631              mpz_clear(u->z);
1632              FREE_RNUMBER(u);
1633              return INT_TO_SR(0);
1634            }
1635            if (mpz_cmp(u->z,a->n)==0)
1636            {
1637              mpz_clear(u->z);
1638              FREE_RNUMBER(u);
1639              return INT_TO_SR(1);
1640            }
1641            mpz_init_set(u->n,a->n);
1642            u->s = 0;
1643            break;
1644          }
1645        } /*switch (b->s) */
1646        break;
1647      }
1648      case 3:
1649      {
1650        switch(b->s)
1651        {
1652          case 0:
1653          case 1:/* a:3, b:1 */
1654          {
1655            mpz_mul(u->z,a->z,b->n);
1656            mpz_add(u->z,u->z,b->z);
1657            if (mpz_cmp_ui(u->z,(long)0)==0)
1658            {
1659              mpz_clear(u->z);
1660              FREE_RNUMBER(u);
1661              return INT_TO_SR(0);
1662            }
1663            if (mpz_cmp(u->z,b->n)==0)
1664            {
1665              mpz_clear(u->z);
1666              FREE_RNUMBER(u);
1667              return INT_TO_SR(1);
1668            }
1669            mpz_init_set(u->n,b->n);
1670            u->s = 0;
1671            break;
1672          }
1673          case 3:
1674          {
1675            mpz_add(u->z,a->z,b->z);
1676            if (mpz_cmp_ui(u->z,(long)0)==0)
1677            {
1678              mpz_clear(u->z);
1679              FREE_RNUMBER(u);
1680              return INT_TO_SR(0);
1681            }
1682            u->s = 3;
1683            u=nlShort3(u);
1684            break;
1685          }
1686        }
1687        break;
1688      }
1689    }
1690  }
1691  return u;
1692}
1693
1694void _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b)
1695{
1696  if (SR_HDL(b) & SR_INT)
1697  {
1698    switch (a->s)
1699    {
1700      case 0:
1701      case 1:/* b:short, a:1 */
1702      {
1703        mpz_t x;
1704        mpz_init(x);
1705        mpz_mul_si(x,a->n,SR_TO_INT(b));
1706        mpz_add(a->z,a->z,x);
1707        mpz_clear(x);
1708        a->s = 0;
1709        a=nlShort1(a);
1710        break;
1711      }
1712      case 3:
1713      {
1714        if ((long)b>0L)
1715          mpz_add_ui(a->z,a->z,SR_TO_INT(b));
1716        else
1717          mpz_sub_ui(a->z,a->z,-SR_TO_INT(b));
1718        a->s = 3;
1719        a=nlShort3_noinline(a);
1720        break;
1721      }
1722    }
1723    return;
1724  }
1725  else if (SR_HDL(a) & SR_INT)
1726  {
1727    number u=ALLOC_RNUMBER();
1728    #if defined(LDEBUG)
1729    u->debug=123456;
1730    #endif
1731    mpz_init(u->z);
1732    switch (b->s)
1733    {
1734      case 0:
1735      case 1:/* a:short, b:1 */
1736      {
1737        mpz_t x;
1738        mpz_init(x);
1739
1740        mpz_mul_si(x,b->n,SR_TO_INT(a));
1741        mpz_add(u->z,b->z,x);
1742        mpz_clear(x);
1743        // result cannot be 0, if coeffs are normalized
1744        mpz_init_set(u->n,b->n);
1745        u->s = 0;
1746        u=nlShort1(u);
1747        break;
1748      }
1749      case 3:
1750      {
1751        if ((long)a>0L)
1752          mpz_add_ui(u->z,b->z,SR_TO_INT(a));
1753        else
1754          mpz_sub_ui(u->z,b->z,-SR_TO_INT(a));
1755        // result cannot be 0, if coeffs are normalized
1756        u->s = 3;
1757        u=nlShort3_noinline(u);
1758        break;
1759      }
1760    }
1761    a=u;
1762  }
1763  else
1764  {
1765    switch (a->s)
1766    {
1767      case 0:
1768      case 1:
1769      {
1770        switch(b->s)
1771        {
1772          case 0:
1773          case 1: /* a:1 b:1 */
1774          {
1775            mpz_t x;
1776            mpz_t y;
1777            mpz_init(x);
1778            mpz_init(y);
1779            mpz_mul(x,b->z,a->n);
1780            mpz_mul(y,a->z,b->n);
1781            mpz_add(a->z,x,y);
1782            mpz_clear(x);
1783            mpz_clear(y);
1784            mpz_mul(a->n,a->n,b->n);
1785            a->s = 0;
1786            break;
1787          }
1788          case 3: /* a:1 b:3 */
1789          {
1790            mpz_t x;
1791            mpz_init(x);
1792            mpz_mul(x,b->z,a->n);
1793            mpz_add(a->z,a->z,x);
1794            mpz_clear(x);
1795            a->s = 0;
1796            break;
1797          }
1798        } /*switch (b->s) */
1799        a=nlShort1(a);
1800        break;
1801      }
1802      case 3:
1803      {
1804        switch(b->s)
1805        {
1806          case 0:
1807          case 1:/* a:3, b:1 */
1808          {
1809            mpz_t x;
1810            mpz_init(x);
1811            mpz_mul(x,a->z,b->n);
1812            mpz_add(a->z,b->z,x);
1813            mpz_clear(x);
1814            mpz_init_set(a->n,b->n);
1815            a->s = 0;
1816            a=nlShort1(a);
1817            break;
1818          }
1819          case 3:
1820          {
1821            mpz_add(a->z,a->z,b->z);
1822            a->s = 3;
1823            a=nlShort3_noinline(a);
1824            break;
1825          }
1826        }
1827        break;
1828      }
1829    }
1830  }
1831}
1832
1833number _nlSub_aNoImm_OR_bNoImm(number a, number b)
1834{
1835  number u=ALLOC_RNUMBER();
1836#if defined(LDEBUG)
1837  u->debug=123456;
1838#endif
1839  mpz_init(u->z);
1840  if (SR_HDL(a) & SR_INT)
1841  {
1842    switch (b->s)
1843    {
1844      case 0:
1845      case 1:/* a:short, b:1 */
1846      {
1847        mpz_t x;
1848        mpz_init(x);
1849        mpz_mul_si(x,b->n,SR_TO_INT(a));
1850        mpz_sub(u->z,x,b->z);
1851        mpz_clear(x);
1852        if (mpz_cmp_ui(u->z,(long)0)==0)
1853        {
1854          mpz_clear(u->z);
1855          FREE_RNUMBER(u);
1856          return INT_TO_SR(0);
1857        }
1858        if (mpz_cmp(u->z,b->n)==0)
1859        {
1860          mpz_clear(u->z);
1861          FREE_RNUMBER(u);
1862          return INT_TO_SR(1);
1863        }
1864        mpz_init_set(u->n,b->n);
1865        u->s = 0;
1866        break;
1867      }
1868      case 3:
1869      {
1870        if ((long)a>0L)
1871        {
1872          mpz_sub_ui(u->z,b->z,SR_TO_INT(a));
1873          mpz_neg(u->z,u->z);
1874        }
1875        else
1876        {
1877          mpz_add_ui(u->z,b->z,-SR_TO_INT(a));
1878          mpz_neg(u->z,u->z);
1879        }
1880        if (mpz_cmp_ui(u->z,(long)0)==0)
1881        {
1882          mpz_clear(u->z);
1883          FREE_RNUMBER(u);
1884          return INT_TO_SR(0);
1885        }
1886        u->s = 3;
1887        u=nlShort3(u);
1888        break;
1889      }
1890    }
1891  }
1892  else if (SR_HDL(b) & SR_INT)
1893  {
1894    switch (a->s)
1895    {
1896      case 0:
1897      case 1:/* b:short, a:1 */
1898      {
1899        mpz_t x;
1900        mpz_init(x);
1901        mpz_mul_si(x,a->n,SR_TO_INT(b));
1902        mpz_sub(u->z,a->z,x);
1903        mpz_clear(x);
1904        if (mpz_cmp_ui(u->z,(long)0)==0)
1905        {
1906          mpz_clear(u->z);
1907          FREE_RNUMBER(u);
1908          return INT_TO_SR(0);
1909        }
1910        if (mpz_cmp(u->z,a->n)==0)
1911        {
1912          mpz_clear(u->z);
1913          FREE_RNUMBER(u);
1914          return INT_TO_SR(1);
1915        }
1916        mpz_init_set(u->n,a->n);
1917        u->s = 0;
1918        break;
1919      }
1920      case 3:
1921      {
1922        if ((long)b>0L)
1923        {
1924          mpz_sub_ui(u->z,a->z,SR_TO_INT(b));
1925        }
1926        else
1927        {
1928          mpz_add_ui(u->z,a->z,-SR_TO_INT(b));
1929        }
1930        if (mpz_cmp_ui(u->z,(long)0)==0)
1931        {
1932          mpz_clear(u->z);
1933          FREE_RNUMBER(u);
1934          return INT_TO_SR(0);
1935        }
1936        u->s = 3;
1937        u=nlShort3(u);
1938        break;
1939      }
1940    }
1941  }
1942  else
1943  {
1944    switch (a->s)
1945    {
1946      case 0:
1947      case 1:
1948      {
1949        switch(b->s)
1950        {
1951          case 0:
1952          case 1:
1953          {
1954            mpz_t x;
1955            mpz_t y;
1956            mpz_init(x);
1957            mpz_init(y);
1958            mpz_mul(x,b->z,a->n);
1959            mpz_mul(y,a->z,b->n);
1960            mpz_sub(u->z,y,x);
1961            mpz_clear(x);
1962            mpz_clear(y);
1963            if (mpz_cmp_ui(u->z,(long)0)==0)
1964            {
1965              mpz_clear(u->z);
1966              FREE_RNUMBER(u);
1967              return INT_TO_SR(0);
1968            }
1969            mpz_init(u->n);
1970            mpz_mul(u->n,a->n,b->n);
1971            if (mpz_cmp(u->z,u->n)==0)
1972            {
1973              mpz_clear(u->z);
1974              mpz_clear(u->n);
1975              FREE_RNUMBER(u);
1976              return INT_TO_SR(1);
1977            }
1978            u->s = 0;
1979            break;
1980          }
1981          case 3: /* a:1, b:3 */
1982          {
1983            mpz_t x;
1984            mpz_init(x);
1985            mpz_mul(x,b->z,a->n);
1986            mpz_sub(u->z,a->z,x);
1987            mpz_clear(x);
1988            if (mpz_cmp_ui(u->z,(long)0)==0)
1989            {
1990              mpz_clear(u->z);
1991              FREE_RNUMBER(u);
1992              return INT_TO_SR(0);
1993            }
1994            if (mpz_cmp(u->z,a->n)==0)
1995            {
1996              mpz_clear(u->z);
1997              FREE_RNUMBER(u);
1998              return INT_TO_SR(1);
1999            }
2000            mpz_init_set(u->n,a->n);
2001            u->s = 0;
2002            break;
2003          }
2004        }
2005        break;
2006      }
2007      case 3:
2008      {
2009        switch(b->s)
2010        {
2011          case 0:
2012          case 1: /* a:3, b:1 */
2013          {
2014            mpz_t x;
2015            mpz_init(x);
2016            mpz_mul(x,a->z,b->n);
2017            mpz_sub(u->z,x,b->z);
2018            mpz_clear(x);
2019            if (mpz_cmp_ui(u->z,(long)0)==0)
2020            {
2021              mpz_clear(u->z);
2022              FREE_RNUMBER(u);
2023              return INT_TO_SR(0);
2024            }
2025            if (mpz_cmp(u->z,b->n)==0)
2026            {
2027              mpz_clear(u->z);
2028              FREE_RNUMBER(u);
2029              return INT_TO_SR(1);
2030            }
2031            mpz_init_set(u->n,b->n);
2032            u->s = 0;
2033            break;
2034          }
2035          case 3: /* a:3 , b:3 */
2036          {
2037            mpz_sub(u->z,a->z,b->z);
2038            if (mpz_cmp_ui(u->z,(long)0)==0)
2039            {
2040              mpz_clear(u->z);
2041              FREE_RNUMBER(u);
2042              return INT_TO_SR(0);
2043            }
2044            u->s = 3;
2045            u=nlShort3(u);
2046            break;
2047          }
2048        }
2049        break;
2050      }
2051    }
2052  }
2053  return u;
2054}
2055
2056// a and b are intermediate, but a*b not
2057number _nlMult_aImm_bImm_rNoImm(number a, number b)
2058{
2059  number u=ALLOC_RNUMBER();
2060#if defined(LDEBUG)
2061  u->debug=123456;
2062#endif
2063  u->s=3;
2064  mpz_init_set_si(u->z,SR_TO_INT(a));
2065  mpz_mul_si(u->z,u->z,SR_TO_INT(b));
2066  return u;
2067}
2068
2069// a or b are not immediate
2070number _nlMult_aNoImm_OR_bNoImm(number a, number b)
2071{
2072  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
2073  number u=ALLOC_RNUMBER();
2074#if defined(LDEBUG)
2075  u->debug=123456;
2076#endif
2077  mpz_init(u->z);
2078  if (SR_HDL(b) & SR_INT)
2079  {
2080    number x=a;
2081    a=b;
2082    b=x;
2083  }
2084  if (SR_HDL(a) & SR_INT)
2085  {
2086    u->s=b->s;
2087    if (u->s==1) u->s=0;
2088    if ((long)a>0L)
2089    {
2090      mpz_mul_ui(u->z,b->z,(unsigned long)SR_TO_INT(a));
2091    }
2092    else
2093    {
2094      if (a==INT_TO_SR(-1))
2095      {
2096        mpz_set(u->z,b->z);
2097        mpz_neg(u->z,u->z);
2098        u->s=b->s;
2099      }
2100      else
2101      {
2102        mpz_mul_ui(u->z,b->z,(unsigned long)-SR_TO_INT(a));
2103        mpz_neg(u->z,u->z);
2104      }
2105    }
2106    if (u->s<2)
2107    {
2108      if (mpz_cmp(u->z,b->n)==0)
2109      {
2110        mpz_clear(u->z);
2111        FREE_RNUMBER(u);
2112        return INT_TO_SR(1);
2113      }
2114      mpz_init_set(u->n,b->n);
2115    }
2116    else //u->s==3
2117    {
2118      u=nlShort3(u);
2119    }
2120  }
2121  else
2122  {
2123    mpz_mul(u->z,a->z,b->z);
2124    u->s = 0;
2125    if(a->s==3)
2126    {
2127      if(b->s==3)
2128      {
2129        u->s = 3;
2130      }
2131      else
2132      {
2133        if (mpz_cmp(u->z,b->n)==0)
2134        {
2135          mpz_clear(u->z);
2136          FREE_RNUMBER(u);
2137          return INT_TO_SR(1);
2138        }
2139        mpz_init_set(u->n,b->n);
2140      }
2141    }
2142    else
2143    {
2144      if(b->s==3)
2145      {
2146        if (mpz_cmp(u->z,a->n)==0)
2147        {
2148          mpz_clear(u->z);
2149          FREE_RNUMBER(u);
2150          return INT_TO_SR(1);
2151        }
2152        mpz_init_set(u->n,a->n);
2153      }
2154      else
2155      {
2156        mpz_init(u->n);
2157        mpz_mul(u->n,a->n,b->n);
2158        if (mpz_cmp(u->z,u->n)==0)
2159        {
2160          mpz_clear(u->z);
2161          mpz_clear(u->n);
2162          FREE_RNUMBER(u);
2163          return INT_TO_SR(1);
2164        }
2165      }
2166    }
2167  }
2168  return u;
2169}
2170
2171/*2
2172* copy a to b for mapping
2173*/
2174number nlCopyMap(number a, const coeffs src, const coeffs dst)
2175{
2176  assume( getCoeffType(dst) == ID );
2177  assume( getCoeffType(src) == ID );
2178  if ((SR_HDL(a) & SR_INT)||(a==NULL))
2179  {
2180    return a;
2181  }
2182  return _nlCopy_NoImm(a);
2183}
2184
2185nMapFunc nlSetMap(const coeffs src, const coeffs dst)
2186{
2187  assume( getCoeffType(dst) == ID );
2188//  assume( getCoeffType(src) == ID );
2189
2190  if (nCoeff_is_Q(src))
2191  {
2192    return ndCopyMap;
2193  }
2194  if (nCoeff_is_Zp(src))
2195  {
2196    return nlMapP;
2197  }
2198  if (nCoeff_is_R(src))
2199  {
2200    return nlMapR;
2201  }
2202  if (nCoeff_is_long_R(src))
2203  {
2204    return nlMapLongR; /* long R -> Q */
2205  }
2206#ifdef HAVE_RINGS
2207  if (nCoeff_is_Ring_Z(src) || nCoeff_is_Ring_PtoM(src) || nCoeff_is_Ring_ModN(src))
2208  {
2209    return nlMapGMP;
2210  }
2211  if (nCoeff_is_Ring_2toM(src))
2212  {
2213    return nlMapMachineInt;
2214  }
2215#endif
2216  return NULL;
2217}
2218/*2
2219* z := i
2220*/
2221number nlRInit (long i)
2222{
2223  number z=ALLOC_RNUMBER();
2224#if defined(LDEBUG)
2225  z->debug=123456;
2226#endif
2227  mpz_init_set_si(z->z,i);
2228  z->s = 3;
2229  return z;
2230}
2231
2232/*2
2233* z := i/j
2234*/
2235number nlInit2 (int i, int j, const coeffs r)
2236{
2237  number z=ALLOC_RNUMBER();
2238#if defined(LDEBUG)
2239  z->debug=123456;
2240#endif
2241  mpz_init_set_si(z->z,(long)i);
2242  mpz_init_set_si(z->n,(long)j);
2243  z->s = 0;
2244  nlNormalize(z,r);
2245  return z;
2246}
2247
2248number nlInit2gmp (mpz_t i, mpz_t j, const coeffs r)
2249{
2250  number z=ALLOC_RNUMBER();
2251#if defined(LDEBUG)
2252  z->debug=123456;
2253#endif
2254  mpz_init_set(z->z,i);
2255  mpz_init_set(z->n,j);
2256  z->s = 0;
2257  nlNormalize(z,r);
2258  return z;
2259}
2260
2261#else // DO_LINLINE
2262
2263// declare immedate routines
2264number nlRInit (long i);
2265BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b);
2266number  _nlCopy_NoImm(number a);
2267number  _nlNeg_NoImm(number a);
2268number  _nlAdd_aNoImm_OR_bNoImm(number a, number b);
2269void    _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b);
2270number  _nlSub_aNoImm_OR_bNoImm(number a, number b);
2271number  _nlMult_aNoImm_OR_bNoImm(number a, number b);
2272number  _nlMult_aImm_bImm_rNoImm(number a, number b);
2273
2274#endif
2275
2276/***************************************************************
2277 *
2278 * Routines which might be inlined by p_Numbers.h
2279 *
2280 *******************************************************************/
2281#if defined(DO_LINLINE) || !defined(P_NUMBERS_H)
2282
2283// routines which are always inlined/static
2284
2285/*2
2286* a = b ?
2287*/
2288LINLINE BOOLEAN nlEqual (number a, number b, const coeffs r)
2289{
2290  nlTest(a, r);
2291  nlTest(b, r);
2292// short - short
2293  if (SR_HDL(a) & SR_HDL(b) & SR_INT) return a==b;
2294  return _nlEqual_aNoImm_OR_bNoImm(a, b);
2295}
2296
2297LINLINE number nlInit (long i, const coeffs r)
2298{
2299  number n;
2300  LONG ii=(LONG)i;
2301  if ( ((ii << 3) >> 3) == ii ) n=INT_TO_SR(ii);
2302  else                          n=nlRInit(ii);
2303  nlTest(n, r);
2304  return n;
2305}
2306
2307/*2
2308* a == 1 ?
2309*/
2310LINLINE BOOLEAN nlIsOne (number a, const coeffs r)
2311{
2312#ifdef LDEBUG
2313  if (a==NULL) return FALSE;
2314  nlTest(a, r);
2315#endif
2316  return (a==INT_TO_SR(1));
2317}
2318
2319LINLINE BOOLEAN nlIsZero (number a, const coeffs)
2320{
2321  #if 0
2322  if (a==INT_TO_SR(0)) return TRUE;
2323  if ((SR_HDL(a) & SR_INT)||(a==NULL)) return FALSE;
2324  if (mpz_cmp_si(a->z,(long)0)==0)
2325  {
2326    printf("gmp-0 in nlIsZero\n");
2327    dErrorBreak();
2328    return TRUE;
2329  }
2330  return FALSE;
2331  #else
2332  return (a==INT_TO_SR(0));
2333  #endif
2334}
2335
2336/*2
2337* copy a to b
2338*/
2339LINLINE number nlCopy(number a, const coeffs)
2340{
2341  if ((SR_HDL(a) & SR_INT)||(a==NULL))
2342  {
2343    return a;
2344  }
2345  return _nlCopy_NoImm(a);
2346}
2347
2348
2349/*2
2350* delete a
2351*/
2352LINLINE void nlDelete (number * a, const coeffs r)
2353{
2354  if (*a!=NULL)
2355  {
2356    nlTest(*a, r);
2357    if ((SR_HDL(*a) & SR_INT)==0)
2358    {
2359      _nlDelete_NoImm(a);
2360    }
2361    *a=NULL;
2362  }
2363}
2364
2365/*2
2366* za:= - za
2367*/
2368LINLINE number nlNeg (number a, const coeffs R)
2369{
2370  nlTest(a, R);
2371  if(SR_HDL(a) &SR_INT)
2372  {
2373    LONG r=SR_TO_INT(a);
2374    if (r==(-(POW_2_28))) a=nlRInit(POW_2_28);
2375    else               a=INT_TO_SR(-r);
2376    return a;
2377  }
2378  a = _nlNeg_NoImm(a);
2379  nlTest(a, R);
2380  return a;
2381
2382}
2383
2384/*2
2385* u:= a + b
2386*/
2387LINLINE number nlAdd (number a, number b, const coeffs R)
2388{
2389  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2390  {
2391    LONG r=SR_HDL(a)+SR_HDL(b)-1L;
2392    if ( ((r << 1) >> 1) == r )
2393      return (number)(long)r;
2394    else
2395      return nlRInit(SR_TO_INT(r));
2396  }
2397  number u =  _nlAdd_aNoImm_OR_bNoImm(a, b);
2398  nlTest(u, R);
2399  return u;
2400}
2401
2402number nlShort1(number a);
2403number nlShort3_noinline(number x);
2404
2405LINLINE void nlInpAdd(number &a, number b, const coeffs r)
2406{
2407  // a=a+b
2408  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2409  {
2410    LONG r=SR_HDL(a)+SR_HDL(b)-1L;
2411    if ( ((r << 1) >> 1) == r )
2412      a=(number)(long)r;
2413    else
2414      a=nlRInit(SR_TO_INT(r));
2415  }
2416  else
2417  {
2418    _nlInpAdd_aNoImm_OR_bNoImm(a,b);
2419    nlTest(a,r);
2420  }
2421}
2422
2423LINLINE number nlMult (number a, number b, const coeffs R)
2424{
2425  nlTest(a, R);
2426  nlTest(b, R);
2427  if (a==INT_TO_SR(0)) return INT_TO_SR(0);
2428  if (b==INT_TO_SR(0)) return INT_TO_SR(0);
2429  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2430  {
2431    LONG r=(LONG)((unsigned LONG)(SR_HDL(a)-1L))*((unsigned LONG)(SR_HDL(b)>>1));
2432    if ((r/(SR_HDL(b)>>1))==(SR_HDL(a)-1L))
2433    {
2434      number u=((number) ((r>>1)+SR_INT));
2435      if (((((LONG)SR_HDL(u))<<1)>>1)==SR_HDL(u)) return (u);
2436      return nlRInit(SR_HDL(u)>>2);
2437    }
2438    number u = _nlMult_aImm_bImm_rNoImm(a, b);
2439    nlTest(u, R);
2440    return u;
2441
2442  }
2443  number u = _nlMult_aNoImm_OR_bNoImm(a, b);
2444  nlTest(u, R);
2445  return u;
2446
2447}
2448
2449
2450/*2
2451* u:= a - b
2452*/
2453LINLINE number nlSub (number a, number b, const coeffs r)
2454{
2455  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2456  {
2457    LONG r=SR_HDL(a)-SR_HDL(b)+1;
2458    if ( ((r << 1) >> 1) == r )
2459    {
2460      return (number)(long)r;
2461    }
2462    else
2463      return nlRInit(SR_TO_INT(r));
2464  }
2465  number u = _nlSub_aNoImm_OR_bNoImm(a, b);
2466  nlTest(u, r);
2467  return u;
2468
2469}
2470
2471LINLINE void nlInpMult(number &a, number b, const coeffs r)
2472{
2473  number aa=a;
2474  if (((SR_HDL(b)|SR_HDL(aa))&SR_INT))
2475  {
2476    number n=nlMult(aa,b,r);
2477    nlDelete(&a,r);
2478    a=n;
2479  }
2480  else
2481  {
2482    mpz_mul(aa->z,a->z,b->z);
2483    if (aa->s==3)
2484    {
2485      if(b->s!=3)
2486      {
2487        mpz_init_set(a->n,b->n);
2488        a->s=0;
2489      }
2490    }
2491    else
2492    {
2493      if(b->s!=3)
2494      {
2495        mpz_mul(a->n,a->n,b->n);
2496      }
2497      a->s=0;
2498    }
2499  }
2500}
2501#endif // DO_LINLINE
2502
2503#ifndef P_NUMBERS_H
2504
2505static void nlMPZ(mpz_t m, number &n, const coeffs r)
2506{
2507  assume( getCoeffType(r) == ID );
2508
2509  nlTest(n, r);
2510  nlNormalize(n, r);
2511  if (SR_HDL(n) & SR_INT) mpz_init_set_si(m, SR_TO_INT(n));     /* n fits in an int */
2512  else             mpz_init_set(m, (mpz_ptr)n->z);
2513}
2514
2515
2516static number nlInitMPZ(mpz_t m, const coeffs)
2517{
2518  number z = ALLOC_RNUMBER();
2519  mpz_init_set(z->z, m);
2520  mpz_init_set_ui(z->n, 1);
2521  z->s = 3;
2522  return z;
2523}
2524
2525
2526void nlInpGcd(number &a, number b, const coeffs r)
2527{
2528  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2529  {
2530    number n=nlGcd(a,b,r);
2531    nlDelete(&a,r);
2532    a=n;
2533  }
2534  else
2535  {
2536    mpz_gcd(a->z,a->z,b->z);
2537    a=nlShort3_noinline(a);
2538  }
2539}
2540
2541void nlInpIntDiv(number &a, number b, const coeffs r)
2542{
2543  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2544  {
2545    number n=nlIntDiv(a,b, r);
2546    nlDelete(&a,r);
2547    a=n;
2548  }
2549  else
2550  {
2551    if (mpz_isNeg(a->z))
2552    {
2553      if (mpz_isNeg(b->z))
2554      {
2555        mpz_add(a->z,a->z,b->z);
2556      }
2557      else
2558      {
2559        mpz_sub(a->z,a->z,b->z);
2560      }
2561      mpz_add_ui(a->z,a->z,1);
2562    }
2563    else
2564    {
2565      if (mpz_isNeg(b->z))
2566      {
2567        mpz_sub(a->z,a->z,b->z);
2568      }
2569      else
2570      {
2571        mpz_add(a->z,a->z,b->z);
2572      }
2573      mpz_sub_ui(a->z,a->z,1);
2574    }
2575    MPZ_DIV(a->z,a->z,b->z);
2576    a=nlShort3_noinline(a);
2577  }
2578}
2579
2580number nlFarey(number nN, number nP, const coeffs r)
2581{
2582  mpz_t tmp; mpz_init(tmp);
2583  mpz_t A,B,C,D,E,N,P;
2584  if (SR_HDL(nN) & SR_INT) mpz_init_set_si(N,SR_TO_INT(nN));
2585  else                     mpz_init_set(N,nN->z);
2586  if (SR_HDL(nP) & SR_INT) mpz_init_set_si(P,SR_TO_INT(nP));
2587  else                     mpz_init_set(P,nP->z);
2588  assume(!mpz_isNeg(P));
2589  if (mpz_isNeg(N))  mpz_add(N,N,P);
2590  mpz_init_set_si(A,(long)0);
2591  mpz_init_set_ui(B,(unsigned long)1);
2592  mpz_init_set_si(C,(long)0);
2593  mpz_init(D);
2594  mpz_init_set(E,P);
2595  number z=INT_TO_SR(0);
2596  while(mpz_cmp_si(N,(long)0)!=0)
2597  {
2598    mpz_mul(tmp,N,N);
2599    mpz_add(tmp,tmp,tmp);
2600    if (mpz_cmp(tmp,P)<0)
2601    {
2602       if (mpz_isNeg(B))
2603       {
2604         mpz_neg(B,B);
2605         mpz_neg(N,N);
2606       }
2607       // check for gcd(N,B)==1
2608       mpz_gcd(tmp,N,B);
2609       if (mpz_cmp_ui(tmp,1)==0)
2610       {
2611         // return N/B
2612         z=ALLOC_RNUMBER();
2613         #ifdef LDEBUG
2614         z->debug=123456;
2615         #endif
2616         mpz_init_set(z->z,N);
2617         mpz_init_set(z->n,B);
2618         z->s = 0;
2619         nlNormalize(z,r);
2620       }
2621       else
2622       {
2623         // return nN (the input) instead of "fail"
2624         z=nlCopy(nN,r);
2625       }
2626       break;
2627    }
2628    //mpz_mod(D,E,N);
2629    //mpz_div(tmp,E,N);
2630    mpz_divmod(tmp,D,E,N);
2631    mpz_mul(tmp,tmp,B);
2632    mpz_sub(C,A,tmp);
2633    mpz_set(E,N);
2634    mpz_set(N,D);
2635    mpz_set(A,B);
2636    mpz_set(B,C);
2637  }
2638  mpz_clear(tmp);
2639  mpz_clear(A);
2640  mpz_clear(B);
2641  mpz_clear(C);
2642  mpz_clear(D);
2643  mpz_clear(E);
2644  mpz_clear(N);
2645  mpz_clear(P);
2646  return z;
2647}
2648
2649number nlExtGcd(number a, number b, number *s, number *t, const coeffs)
2650{
2651  mpz_t aa,bb;
2652  *s=ALLOC_RNUMBER();
2653  mpz_init((*s)->z); (*s)->s=3;
2654  (*t)=ALLOC_RNUMBER();
2655  mpz_init((*t)->z); (*t)->s=3;
2656  number g=ALLOC_RNUMBER();
2657  mpz_init(g->z); g->s=3;
2658  if (SR_HDL(a) & SR_INT)
2659  {
2660    mpz_init_set_si(aa,SR_TO_INT(a));
2661  }
2662  else
2663  {
2664    mpz_init_set(aa,a->z);
2665  }
2666  if (SR_HDL(b) & SR_INT)
2667  {
2668    mpz_init_set_si(bb,SR_TO_INT(b));
2669  }
2670  else
2671  {
2672    mpz_init_set(bb,b->z);
2673  }
2674  mpz_gcdext(g->z,(*s)->z,(*t)->z,aa,bb);
2675  mpz_clear(aa);
2676  mpz_clear(bb);
2677  (*s)=nlShort3((*s));
2678  (*t)=nlShort3((*t));
2679  g=nlShort3(g);
2680  return g;
2681}
2682
2683void    nlCoeffWrite  (const coeffs, BOOLEAN /*details*/)
2684{
2685  PrintS("//   characteristic : 0\n");
2686}
2687
2688number   nlChineseRemainderSym(number *x, number *q,int rl, BOOLEAN sym, const coeffs CF)
2689// elemenst in the array are x[0..(rl-1)], q[0..(rl-1)]
2690{
2691  setCharacteristic( 0 ); // only in char 0
2692  Off(SW_RATIONAL);
2693  CFArray X(rl), Q(rl);
2694  int i;
2695  for(i=rl-1;i>=0;i--)
2696  {
2697    X[i]=CF->convSingNFactoryN(x[i],FALSE,CF); // may be larger MAX_INT
2698    Q[i]=CF->convSingNFactoryN(q[i],FALSE,CF); // may be larger MAX_INT
2699  }
2700  CanonicalForm xnew,qnew;
2701  chineseRemainder(X,Q,xnew,qnew);
2702  number n=CF->convFactoryNSingN(xnew,CF);
2703  if (sym)
2704  {
2705    number p=CF->convFactoryNSingN(qnew,CF);
2706    number p2=nlIntDiv(p,nlInit(2, CF),CF);
2707    if (nlGreater(n,p2,CF))
2708    {
2709       number n2=nlSub(n,p,CF);
2710       nlDelete(&n,CF);
2711       n=n2;
2712    }
2713    nlDelete(&p2,CF);
2714    nlDelete(&p,CF);
2715  }
2716  nlNormalize(n,CF);
2717  return n;
2718}
2719number   nlChineseRemainder(number *x, number *q,int rl, const coeffs C)
2720{
2721  return nlChineseRemainderSym(x,q,rl,TRUE,C);
2722}
2723
2724static void nlClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
2725{
2726  assume(cf != NULL);
2727  assume(getCoeffType(cf) == ID);
2728
2729  numberCollectionEnumerator.Reset();
2730
2731  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
2732  {
2733    c = n_Init(1, cf);
2734    return;
2735  }
2736
2737  // all coeffs are given by integers!!!
2738
2739  // part 1, find a small candidate for gcd
2740  number cand1,cand;
2741  int s1,s;
2742  s=2147483647; // max. int
2743
2744  const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf);
2745
2746  int normalcount = 0;
2747  do
2748  {
2749    number& n = numberCollectionEnumerator.Current();
2750    nlNormalize(n, cf); ++normalcount;
2751    cand1 = n;
2752
2753    if (SR_HDL(cand1)&SR_INT) { cand=cand1; break; }
2754    assume(cand1->s==3); // all coeffs should be integers // ==0?!! after printing
2755    s1=mpz_size1(cand1->z);
2756    if (s>s1)
2757    {
2758      cand=cand1;
2759      s=s1;
2760    }
2761  } while (numberCollectionEnumerator.MoveNext() );
2762
2763//  assume( nlGreaterZero(cand,cf) ); // cand may be a negative integer!
2764
2765  cand=nlCopy(cand,cf);
2766  // part 2: compute gcd(cand,all coeffs)
2767
2768  numberCollectionEnumerator.Reset();
2769
2770  while (numberCollectionEnumerator.MoveNext() )
2771  {
2772    number& n = numberCollectionEnumerator.Current();
2773
2774    if( (--normalcount) <= 0)
2775      nlNormalize(n, cf);
2776
2777    nlInpGcd(cand, n, cf);
2778    assume( nlGreaterZero(cand,cf) );
2779
2780    if(nlIsOne(cand,cf))
2781    {
2782      c = cand;
2783
2784      if(!lc_is_pos)
2785      {
2786        // make the leading coeff positive
2787        c = nlNeg(c, cf);
2788        numberCollectionEnumerator.Reset();
2789
2790        while (numberCollectionEnumerator.MoveNext() )
2791        {
2792          number& nn = numberCollectionEnumerator.Current();
2793          nn = nlNeg(nn, cf);
2794        }
2795      }
2796      return;
2797    }
2798  }
2799
2800  // part3: all coeffs = all coeffs / cand
2801  if (!lc_is_pos)
2802    cand = nlNeg(cand,cf);
2803
2804  c = cand;
2805  numberCollectionEnumerator.Reset();
2806
2807  while (numberCollectionEnumerator.MoveNext() )
2808  {
2809    number& n = numberCollectionEnumerator.Current();
2810    number t=nlIntDiv(n, cand, cf); // simple integer exact division, no ratios to remain
2811    nlDelete(&n, cf);
2812    n = t;
2813  }
2814}
2815
2816static void nlClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
2817{
2818  assume(cf != NULL);
2819  assume(getCoeffType(cf) == ID);
2820
2821  numberCollectionEnumerator.Reset();
2822
2823  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
2824  {
2825    c = n_Init(1, cf);
2826//    assume( n_GreaterZero(c, cf) );
2827    return;
2828  }
2829
2830  // all coeffs are given by integers after returning from this routine
2831
2832  // part 1, collect product of all denominators /gcds
2833  number cand;
2834  cand=ALLOC_RNUMBER();
2835#if defined(LDEBUG)
2836  cand->debug=123456;
2837#endif
2838  cand->s=3;
2839
2840  int s=0;
2841
2842  const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf);
2843
2844  do
2845  {
2846    number& cand1 = numberCollectionEnumerator.Current();
2847
2848    if (!(SR_HDL(cand1)&SR_INT))
2849    {
2850      nlNormalize(cand1, cf);
2851      if ((!(SR_HDL(cand1)&SR_INT)) // not a short int
2852      && (cand1->s==1))             // and is a normalised rational
2853      {
2854        if (s==0) // first denom, we meet
2855        {
2856          mpz_init_set(cand->z, cand1->n); // cand->z = cand1->n
2857          s=1;
2858        }
2859        else // we have already something
2860        {
2861          mpz_lcm(cand->z, cand->z, cand1->n);
2862        }
2863      }
2864    }
2865  }
2866  while (numberCollectionEnumerator.MoveNext() );
2867
2868
2869  if (s==0) // nothing to do, all coeffs are already integers
2870  {
2871//    mpz_clear(tmp);
2872    FREE_RNUMBER(cand);
2873    if (lc_is_pos)
2874      c=nlInit(1,cf);
2875    else
2876    {
2877      // make the leading coeff positive
2878      c=nlInit(-1,cf);
2879
2880      // TODO: incorporate the following into the loop below?
2881      numberCollectionEnumerator.Reset();
2882      while (numberCollectionEnumerator.MoveNext() )
2883      {
2884        number& n = numberCollectionEnumerator.Current();
2885        n = nlNeg(n, cf);
2886      }
2887    }
2888//    assume( n_GreaterZero(c, cf) );
2889    return;
2890  }
2891
2892  cand = nlShort3(cand);
2893
2894  // part2: all coeffs = all coeffs * cand
2895  // make the lead coeff positive
2896  numberCollectionEnumerator.Reset();
2897
2898  if (!lc_is_pos)
2899    cand = nlNeg(cand, cf);
2900
2901  c = cand;
2902
2903  while (numberCollectionEnumerator.MoveNext() )
2904  {
2905    number &n = numberCollectionEnumerator.Current();
2906    n_InpMult(n, cand, cf);
2907  }
2908
2909}
2910
2911static char* nlCoeffString(const coeffs)
2912{
2913  return omStrDup("0");
2914}
2915
2916#define SSI_BASE 16
2917
2918static void nlWriteFd(number n,FILE* f, const coeffs)
2919{
2920  if(SR_HDL(n) & SR_INT)
2921  {
2922    #if SIZEOF_LONG == 4
2923    fprintf(f,"4 %ld ",SR_TO_INT(n));
2924    #else
2925    long nn=SR_TO_INT(n);
2926    if ((nn<POW_2_28)||(nn>= -POW_2_28))
2927      fprintf(f,"4 %ld ",nn);
2928    else
2929    {
2930      mpz_t tmp;
2931      mpz_init_set_si(tmp,nn);
2932      fputs("8 ",f);
2933      mpz_out_str (f,SSI_BASE, tmp);
2934      fputc(' ',f);
2935      mpz_clear(tmp);
2936    }
2937    #endif
2938  }
2939  else if (n->s<2)
2940  {
2941    //gmp_fprintf(f,"%d %Zd %Zd ",n->s,n->z,n->n);
2942    fprintf(f,"%d ",n->s+5);
2943    mpz_out_str (f,SSI_BASE, n->z);
2944    fputc(' ',f);
2945    mpz_out_str (f,SSI_BASE, n->n);
2946    fputc(' ',f);
2947
2948    //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: s=%d gmp/gmp \"%Zd %Zd\" ",n->s,n->z,n->n);
2949  }
2950  else /*n->s==3*/
2951  {
2952    //gmp_fprintf(d->f_write,"3 %Zd ",n->z);
2953    fputs("8 ",f);
2954    mpz_out_str (f,SSI_BASE, n->z);
2955    fputc(' ',f);
2956
2957    //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: gmp \"%Zd\" ",n->z);
2958  }
2959}
2960
2961static number nlReadFd(s_buff f, const coeffs)
2962{
2963  int sub_type=-1;
2964  sub_type=s_readint(f);
2965  switch(sub_type)
2966  {
2967     case 0:
2968     case 1:
2969       {// read mpz_t, mpz_t
2970         number n=nlRInit(0);
2971         mpz_init(n->n);
2972         s_readmpz(f,n->z);
2973         s_readmpz(f,n->n);
2974         n->s=sub_type;
2975         return n;
2976       }
2977
2978     case 3:
2979       {// read mpz_t
2980         number n=nlRInit(0);
2981         s_readmpz(f,n->z);
2982         n->s=3; /*sub_type*/
2983         #if SIZEOF_LONG == 8
2984         n=nlShort3(n);
2985         #endif
2986         return n;
2987       }
2988     case 4:
2989       {
2990         LONG dd=s_readlong(f);
2991         //#if SIZEOF_LONG == 8
2992         return INT_TO_SR(dd);
2993         //#else
2994         //return nlInit(dd,NULL);
2995         //#endif
2996       }
2997     case 5:
2998     case 6:
2999       {// read raw mpz_t, mpz_t
3000         number n=nlRInit(0);
3001         mpz_init(n->n);
3002         s_readmpz_base (f,n->z, SSI_BASE);
3003         s_readmpz_base (f,n->n, SSI_BASE);
3004         n->s=sub_type-5;
3005         return n;
3006       }
3007     case 8:
3008       {// read raw mpz_t
3009         number n=nlRInit(0);
3010         s_readmpz_base (f,n->z, SSI_BASE);
3011         n->s=sub_type=3; /*subtype-5*/
3012         #if SIZEOF_LONG == 8
3013         n=nlShort3(n);
3014         #endif
3015         return n;
3016       }
3017
3018     default: Werror("error in reading number: invalid subtype %d",sub_type);
3019              return NULL;
3020  }
3021  return NULL;
3022}
3023BOOLEAN nlCoeffIsEqual(const coeffs r, n_coeffType n, void *p)
3024{
3025  /* test, if r is an instance of nInitCoeffs(n,parameter) */
3026  /* if paramater is not needed */
3027  if (n==r->type)
3028  {
3029    if ((p==NULL)&&(r->cfDiv==nlDiv)) return TRUE;
3030    if ((p!=NULL)&&(r->cfDiv!=nlDiv)) return TRUE;
3031  }
3032  return FALSE;
3033}
3034
3035
3036
3037BOOLEAN nlInitChar(coeffs r, void*p)
3038{
3039  assume( getCoeffType(r) == ID );
3040  //const int ch = (int)(long)(p);
3041
3042  r->nCoeffIsEqual=nlCoeffIsEqual;
3043  r->cfKillChar = ndKillChar; /* dummy */
3044  r->cfCoeffString=nlCoeffString;
3045
3046  r->cfInitMPZ = nlInitMPZ;
3047  r->cfMPZ  = nlMPZ;
3048
3049  r->cfMult  = nlMult;
3050  r->cfSub   = nlSub;
3051  r->cfAdd   = nlAdd;
3052  if (p==NULL) r->cfDiv   = nlDiv;
3053  else         r->cfDiv   = nlIntDiv;
3054  r->cfIntDiv= nlIntDiv;
3055  r->cfIntMod= nlIntMod;
3056  r->cfExactDiv= nlExactDiv;
3057  r->cfInit = nlInit;
3058  r->cfSize  = nlSize;
3059  r->cfInt  = nlInt;
3060
3061  r->cfChineseRemainder=nlChineseRemainderSym;
3062  r->cfFarey=nlFarey;
3063  #ifdef HAVE_RINGS
3064  //r->cfDivComp = NULL; // only for ring stuff
3065  //r->cfIsUnit = NULL; // only for ring stuff
3066  //r->cfGetUnit = NULL; // only for ring stuff
3067  //r->cfDivBy = NULL; // only for ring stuff
3068  #endif
3069  r->cfInpNeg   = nlNeg;
3070  r->cfInvers= nlInvers;
3071  r->cfCopy  = nlCopy;
3072  r->cfRePart = nlCopy;
3073  //r->cfImPart = ndReturn0;
3074  r->cfWriteLong = nlWrite;
3075  r->cfRead = nlRead;
3076  r->cfNormalize=nlNormalize;
3077  r->cfGreater = nlGreater;
3078  r->cfEqual = nlEqual;
3079  r->cfIsZero = nlIsZero;
3080  r->cfIsOne = nlIsOne;
3081  r->cfIsMOne = nlIsMOne;
3082  r->cfGreaterZero = nlGreaterZero;
3083  r->cfPower = nlPower;
3084  r->cfGetDenom = nlGetDenom;
3085  r->cfGetNumerator = nlGetNumerator;
3086  r->cfGcd  = nlGcd;
3087  r->cfExtGcd = nlExtGcd; // only for ring stuff and Z
3088  r->cfLcm  = nlLcm;
3089  r->cfDelete= nlDelete;
3090  r->cfSetMap = nlSetMap;
3091  //r->cfName = ndName;
3092  r->cfInpMult=nlInpMult;
3093  r->cfInpAdd=nlInpAdd;
3094  r->cfInit_bigint=nlCopyMap;
3095  r->cfCoeffWrite=nlCoeffWrite;
3096
3097  r->cfClearContent = nlClearContent;
3098  r->cfClearDenominators = nlClearDenominators;
3099
3100#ifdef LDEBUG
3101  // debug stuff
3102  r->cfDBTest=nlDBTest;
3103#endif
3104  r->convSingNFactoryN=nlConvSingNFactoryN;
3105  r->convFactoryNSingN=nlConvFactoryNSingN;
3106
3107  // io via ssi
3108  r->cfWriteFd=nlWriteFd;
3109  r->cfReadFd=nlReadFd;
3110
3111  // the variables: general stuff (required)
3112  r->nNULL = INT_TO_SR(0);
3113  //r->type = n_Q;
3114  r->ch = 0;
3115  r->has_simple_Alloc=FALSE;
3116  r->has_simple_Inverse=FALSE;
3117
3118  // variables for this type of coeffs:
3119  // (none)
3120  return FALSE;
3121}
3122#if 0
3123number nlMod(number a, number b)
3124{
3125  if (((SR_HDL(b)&SR_HDL(a))&SR_INT)
3126  {
3127    int bi=SR_TO_INT(b);
3128    int ai=SR_TO_INT(a);
3129    int bb=ABS(bi);
3130    int c=ai%bb;
3131    if (c<0)  c+=bb;
3132    return (INT_TO_SR(c));
3133  }
3134  number al;
3135  number bl;
3136  if (SR_HDL(a))&SR_INT)
3137    al=nlRInit(SR_TO_INT(a));
3138  else
3139    al=nlCopy(a);
3140  if (SR_HDL(b))&SR_INT)
3141    bl=nlRInit(SR_TO_INT(b));
3142  else
3143    bl=nlCopy(b);
3144  number r=nlRInit(0);
3145  mpz_mod(r->z,al->z,bl->z);
3146  nlDelete(&al);
3147  nlDelete(&bl);
3148  if (mpz_size1(&r->z)<=MP_SMALL)
3149  {
3150    LONG ui=(int)mpz_get_si(&r->z);
3151    if ((((ui<<3)>>3)==ui)
3152    && (mpz_cmp_si(x->z,(long)ui)==0))
3153    {
3154      mpz_clear(&r->z);
3155      FREE_RNUMBER(r); //  omFreeBin((void *)r, rnumber_bin);
3156      r=INT_TO_SR(ui);
3157    }
3158  }
3159  return r;
3160}
3161#endif
3162#endif // not P_NUMBERS_H
3163#endif // LONGRAT_CC
Note: See TracBrowser for help on using the repository browser.