source: git/libpolys/coeffs/longrat.cc @ 0461f0

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