source: git/libpolys/coeffs/longrat.cc @ 577888

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