source: git/libpolys/coeffs/longrat.cc @ 045efb

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