source: git/libpolys/coeffs/longrat.cc @ 2f0314

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