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

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