source: git/libpolys/coeffs/longrat.cc @ 88615db

spielwiese
Last change on this file since 88615db was 88615db, checked in by jgmbenoit <quatermaster@…>, 9 years ago
correct some spelling errors: Correct spelling error as reported by lintian in some binraries; meant to silence lintian.
  • Property mode set to 100644
File size: 66.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: computation with long rational numbers (Hubert Grassmann)
6*/
7
8#include <misc/auxiliary.h>
9#include <omalloc/omalloc.h>
10
11#include <factory/factory.h>
12
13#include <misc/sirandom.h>
14#include <reporter/reporter.h>
15
16#include "rmodulon.h" // ZnmInfo
17#include "longrat.h"
18#include "shortfl.h"
19#include "modulop.h"
20
21// allow inlining only from p_Numbers.h and if ! LDEBUG
22#if defined(DO_LINLINE) && defined(P_NUMBERS_H) && !defined(LDEBUG)
23#define LINLINE static FORCE_INLINE
24#else
25#define LINLINE
26#undef DO_LINLINE
27#endif // DO_LINLINE
28
29LINLINE BOOLEAN  nlEqual(number a, number b, const coeffs r);
30LINLINE number   nlInit(long i, const coeffs r);
31LINLINE BOOLEAN  nlIsOne(number a, const coeffs r);
32LINLINE BOOLEAN  nlIsZero(number za, const coeffs r);
33LINLINE number   nlCopy(number a, const coeffs r);
34LINLINE number   nl_Copy(number a, const coeffs r);
35LINLINE void     nlDelete(number *a, const coeffs r);
36LINLINE number   nlNeg(number za, const coeffs r);
37LINLINE number   nlAdd(number la, number li, const coeffs r);
38LINLINE number   nlSub(number la, number li, const coeffs r);
39LINLINE number   nlMult(number a, number b, const coeffs r);
40LINLINE void nlInpAdd(number &a, number b, const coeffs r);
41LINLINE void nlInpMult(number &a, number b, const coeffs r);
42
43number nlRInit (long i);
44
45
46// number nlInitMPZ(mpz_t m, const coeffs r);
47// void nlMPZ(mpz_t m, number &n, const coeffs r);
48
49void     nlNormalize(number &x, const coeffs r);
50
51number   nlGcd(number a, number b, const coeffs r);
52number nlExtGcd(number a, number b, number *s, number *t, const coeffs);
53number   nlNormalizeHelper(number a, number b, const coeffs r);   /*special routine !*/
54BOOLEAN  nlGreater(number a, number b, const coeffs r);
55BOOLEAN  nlIsMOne(number a, const coeffs r);
56long     nlInt(number &n, const coeffs r);
57number   nlBigInt(number &n);
58
59#ifdef HAVE_RINGS
60number nlMapGMP(number from, const coeffs src, const coeffs dst);
61#endif
62
63BOOLEAN  nlGreaterZero(number za, const coeffs r);
64number   nlInvers(number a, const coeffs r);
65number   nlDiv(number a, number b, const coeffs r);
66number   nlExactDiv(number a, number b, const coeffs r);
67number   nlIntDiv(number a, number b, const coeffs r);
68number   nlIntMod(number a, number b, const coeffs r);
69void     nlPower(number x, int exp, number *lu, const coeffs r);
70const char *   nlRead (const char *s, number *a, const coeffs r);
71void     nlWrite(number &a, const coeffs r);
72
73number   nlGetDenom(number &n, const coeffs r);
74number   nlGetNumerator(number &n, const coeffs r);
75void     nlCoeffWrite(const coeffs r, BOOLEAN details);
76number   nlChineseRemainder(number *x, number *q,int rl, const coeffs C);
77number   nlFarey(number nN, number nP, const coeffs CF);
78
79#ifdef LDEBUG
80BOOLEAN  nlDBTest(number a, const char *f, const int l);
81#endif
82
83nMapFunc nlSetMap(const coeffs src, const coeffs dst);
84
85// in-place operations
86void nlInpIntDiv(number &a, number b, const coeffs r);
87
88#ifdef LDEBUG
89#define nlTest(a, r) nlDBTest(a,__FILE__,__LINE__, r)
90BOOLEAN nlDBTest(number a, char *f,int l, const coeffs r);
91#else
92#define nlTest(a, r) do {} while (0)
93#endif
94
95
96// 64 bit version:
97//#if SIZEOF_LONG == 8
98#if 0
99#define MAX_NUM_SIZE 60
100#define POW_2_28 (1L<<60)
101#define POW_2_28_32 (1L<<28)
102#define LONG long
103#else
104#define MAX_NUM_SIZE 28
105#define POW_2_28 (1L<<28)
106#define POW_2_28_32 (1L<<28)
107#define LONG int
108#endif
109
110static inline number nlShort3(number x) // assume x->s==3
111{
112  assume(x->s==3);
113  if (mpz_cmp_ui(x->z,(long)0)==0)
114  {
115    mpz_clear(x->z);
116    FREE_RNUMBER(x);
117    return INT_TO_SR(0);
118  }
119  if (mpz_size1(x->z)<=MP_SMALL)
120  {
121    LONG ui=mpz_get_si(x->z);
122    if ((((ui<<3)>>3)==ui)
123    && (mpz_cmp_si(x->z,(long)ui)==0))
124    {
125      mpz_clear(x->z);
126      FREE_RNUMBER(x);
127      return INT_TO_SR(ui);
128    }
129  }
130  return x;
131}
132
133#ifndef LONGRAT_CC
134#define LONGRAT_CC
135
136#include <string.h>
137#include <float.h>
138
139#include <coeffs/coeffs.h>
140#include <reporter/reporter.h>
141#include <omalloc/omalloc.h>
142
143#include <coeffs/numbers.h>
144#include <coeffs/mpr_complex.h>
145
146#ifndef BYTES_PER_MP_LIMB
147#define BYTES_PER_MP_LIMB sizeof(mp_limb_t)
148#endif
149
150//#define SR_HDL(A) ((long)(A))
151/*#define SR_INT    1L*/
152/*#define INT_TO_SR(INT)  ((number) (((long)INT << 2) + SR_INT))*/
153// #define SR_TO_INT(SR)   (((long)SR) >> 2)
154
155#define MP_SMALL 1
156//#define mpz_isNeg(A) (mpz_cmp_si(A,(long)0)<0)
157#define mpz_isNeg(A) ((A)->_mp_size<0)
158#define mpz_limb_size(A) ((A)->_mp_size)
159#define mpz_limb_d(A) ((A)->_mp_d)
160#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
161#define MPZ_EXACTDIV(A,B,C) mpz_divexact((A),(B),(C))
162
163void    _nlDelete_NoImm(number *a);
164
165/***************************************************************
166 *
167 * Routines which are never inlined by p_Numbers.h
168 *
169 *******************************************************************/
170#ifndef P_NUMBERS_H
171
172number nlShort3_noinline(number x) // assume x->s==3
173{
174  return nlShort3(x);
175}
176
177
178#if (__GNU_MP_VERSION*10+__GNU_MP_VERSION_MINOR < 31)
179void mpz_mul_si (mpz_ptr r, mpz_srcptr s, long int si)
180{
181  if (si>=0)
182    mpz_mul_ui(r,s,si);
183  else
184  {
185    mpz_mul_ui(r,s,-si);
186    mpz_neg(r,r);
187  }
188}
189#endif
190
191static number nlMapP(number from, const coeffs src, const coeffs dst)
192{
193  assume( getCoeffType(src) == n_Zp );
194
195  number to = nlInit(npInt(from,src), dst); // FIXME? TODO? // extern long     npInt         (number &n, const coeffs r);
196
197  return to;
198}
199
200static number nlMapLongR(number from, const coeffs src, const coeffs dst);
201static number nlMapR(number from, const coeffs src, const coeffs dst);
202
203
204#ifdef HAVE_RINGS
205/*2
206* convert from a GMP integer
207*/
208number nlMapGMP(number from, const coeffs /*src*/, const coeffs /*dst*/)
209{
210  number z=ALLOC_RNUMBER();
211#if defined(LDEBUG)
212  z->debug=123456;
213#endif
214  mpz_init_set(z->z,(mpz_ptr) from);
215  //mpz_init_set_ui(&z->n,1);
216  z->s = 3;
217  z=nlShort3(z);
218  return z;
219}
220
221number nlMapZ(number from, const coeffs src, const coeffs dst)
222{
223  if (SR_HDL(from) & SR_INT)
224  {
225    return from;
226  }
227  return nlMapGMP(from,src,dst);
228}
229
230/*2
231* convert from an machine long
232*/
233number nlMapMachineInt(number from, const coeffs /*src*/, const coeffs /*dst*/)
234{
235  number z=ALLOC_RNUMBER();
236#if defined(LDEBUG)
237  z->debug=123456;
238#endif
239  mpz_init_set_ui(z->z,(unsigned long) from);
240  z->s = 3;
241  z=nlShort3(z);
242  return z;
243}
244#endif
245
246
247#ifdef LDEBUG
248BOOLEAN nlDBTest(number a, const char *f,const int l, const coeffs /*r*/)
249{
250  if (a==NULL)
251  {
252    Print("!!longrat: NULL in %s:%d\n",f,l);
253    return FALSE;
254  }
255  //if ((int)a==1) Print("!! 0x1 as number ? %s %d\n",f,l);
256  if ((((long)a)&3L)==3L)
257  {
258    Print(" !!longrat:ptr(3) in %s:%d\n",f,l);
259    return FALSE;
260  }
261  if ((((long)a)&3L)==1L)
262  {
263    if (((((LONG)(long)a)<<1)>>1)!=((LONG)(long)a))
264    {
265      Print(" !!longrat:arith:%lx in %s:%d\n",(long)a, f,l);
266      return FALSE;
267    }
268    return TRUE;
269  }
270  /* TODO: If next line is active, then computations in algebraic field
271           extensions over Q will throw a lot of assume violations although
272           everything is computed correctly and no seg fault appears.
273           Maybe the test is not appropriate in this case. */
274  omCheckIf(omCheckAddrSize(a,sizeof(*a)), return FALSE);
275  if (a->debug!=123456)
276  {
277    Print("!!longrat:debug:%d in %s:%d\n",a->debug,f,l);
278    a->debug=123456;
279    return FALSE;
280  }
281  if ((a->s<0)||(a->s>4))
282  {
283    Print("!!longrat:s=%d in %s:%d\n",a->s,f,l);
284    return FALSE;
285  }
286  /* TODO: If next line is active, then computations in algebraic field
287           extensions over Q will throw a lot of assume violations although
288           everything is computed correctly and no seg fault appears.
289           Maybe the test is not appropriate in this case. */
290  //omCheckAddrSize(a->z[0]._mp_d,a->z[0]._mp_alloc*BYTES_PER_MP_LIMB);
291  if (a->z[0]._mp_alloc==0)
292    Print("!!longrat:z->alloc=0 in %s:%d\n",f,l);
293
294  if (a->s<2)
295  {
296    if ((a->n[0]._mp_d[0]==0)&&(a->n[0]._mp_alloc<=1))
297    {
298      Print("!!longrat: n==0 in %s:%d\n",f,l);
299      return FALSE;
300    }
301    /* TODO: If next line is active, then computations in algebraic field
302             extensions over Q will throw a lot of assume violations although
303             everything is computed correctly and no seg fault appears.
304             Maybe the test is not appropriate in this case. */
305    //omCheckIf(omCheckAddrSize(a->n[0]._mp_d,a->n[0]._mp_alloc*BYTES_PER_MP_LIMB), return FALSE);
306    if (a->z[0]._mp_alloc==0)
307      Print("!!longrat:n->alloc=0 in %s:%d\n",f,l);
308    if ((mpz_size1(a->n) ==1) && (mpz_cmp_si(a->n,(long)1)==0))
309    {
310      Print("!!longrat:integer as rational in %s:%d\n",f,l);
311      mpz_clear(a->n); a->s=3;
312      return FALSE;
313    }
314    else if (mpz_isNeg(a->n))
315    {
316      Print("!!longrat:div. by negative in %s:%d\n",f,l);
317      mpz_neg(a->z,a->z);
318      mpz_neg(a->n,a->n);
319      return FALSE;
320    }
321    return TRUE;
322  }
323  //if (a->s==2)
324  //{
325  //  Print("!!longrat:s=2 in %s:%d\n",f,l);
326  //  return FALSE;
327  //}
328  if (mpz_size1(a->z)>MP_SMALL) return TRUE;
329  LONG ui=(LONG)mpz_get_si(a->z);
330  if ((((ui<<3)>>3)==ui)
331  && (mpz_cmp_si(a->z,(long)ui)==0))
332  {
333    Print("!!longrat:im int %d in %s:%d\n",ui,f,l);
334    return FALSE;
335  }
336  return TRUE;
337}
338#endif
339
340static CanonicalForm nlConvSingNFactoryN( number n, const BOOLEAN setChar, const coeffs /*r*/ )
341{
342  if (setChar) setCharacteristic( 0 );
343
344  CanonicalForm term;
345  if ( SR_HDL(n) & SR_INT )
346  {
347    long nn=SR_TO_INT(n);
348    term = nn;
349  }
350  else
351  {
352    if ( n->s == 3 )
353    {
354      mpz_t dummy;
355      long lz=mpz_get_si(n->z);
356      if (mpz_cmp_si(n->z,lz)==0) term=lz;
357      else
358      {
359        mpz_init_set( dummy,n->z );
360        term = make_cf( dummy );
361      }
362    }
363    else
364    {
365      // assume s==0 or s==1
366      mpz_t num, den;
367      On(SW_RATIONAL);
368      mpz_init_set( num, n->z );
369      mpz_init_set( den, n->n );
370      term = make_cf( num, den, ( n->s != 1 ));
371    }
372  }
373  return term;
374}
375
376number nlRInit (long i);
377
378static number nlConvFactoryNSingN( const CanonicalForm f, const coeffs r)
379{
380  if (f.isImm())
381  {
382    return nlInit(f.intval(),r);
383  }
384  else
385  {
386    number z = ALLOC_RNUMBER(); //Q!? // (number)omAllocBin(rnumber_bin);
387#if defined(LDEBUG)
388    z->debug=123456;
389#endif
390    gmp_numerator( f, z->z );
391    if ( f.den().isOne() )
392      z->s = 3;
393    else
394    {
395      gmp_denominator( f, z->n );
396      z->s = 0;
397    }
398    nlNormalize(z,r);
399    return z;
400  }
401}
402
403static number nlMapR(number from, const coeffs src, const coeffs dst)
404{
405  assume( getCoeffType(src) == n_R );
406
407  double f=nrFloat(from); // FIXME? TODO? // extern float   nrFloat(number n);
408  if (f==0.0) return INT_TO_SR(0);
409  int f_sign=1;
410  if (f<0.0)
411  {
412    f_sign=-1;
413    f=-f;
414  }
415  int i=0;
416  mpz_t h1;
417  mpz_init_set_ui(h1,1);
418  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
419  {
420    f*=FLT_RADIX;
421    mpz_mul_ui(h1,h1,FLT_RADIX);
422    i++;
423  }
424  number re=nlRInit(1);
425  mpz_set_d(re->z,f);
426  memcpy(&(re->n),&h1,sizeof(h1));
427  re->s=0; /* not normalized */
428  if(f_sign==-1) re=nlNeg(re,dst);
429  nlNormalize(re,dst);
430  return re;
431}
432
433static number nlMapLongR(number from, const coeffs src, const coeffs dst)
434{
435  assume( getCoeffType(src) == n_long_R );
436
437  gmp_float *ff=(gmp_float*)from;
438  mpf_t *f=ff->_mpfp();
439  number res;
440  mpz_ptr dest,ndest;
441  int size, i,negative;
442  int e,al,bl;
443  mp_ptr qp,dd,nn;
444
445  size = (*f)[0]._mp_size;
446  if (size == 0)
447    return INT_TO_SR(0);
448  if(size<0)
449  {
450    negative = 1;
451    size = -size;
452  }
453  else
454    negative = 0;
455
456  qp = (*f)[0]._mp_d;
457  while(qp[0]==0)
458  {
459    qp++;
460    size--;
461  }
462
463  e=(*f)[0]._mp_exp-size;
464  res = ALLOC_RNUMBER();
465#if defined(LDEBUG)
466  res->debug=123456;
467#endif
468  dest = res->z;
469
470  if (e<0)
471  {
472    al = dest->_mp_size = size;
473    if (al<2) al = 2;
474    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
475    for (i=0;i<size;i++) dd[i] = qp[i];
476    bl = 1-e;
477    nn = (mp_ptr)omAlloc(sizeof(mp_limb_t)*bl);
478    nn[bl-1] = 1;
479    for (i=bl-2;i>=0;i--) nn[i] = 0;
480    ndest = res->n;
481    ndest->_mp_d = nn;
482    ndest->_mp_alloc = ndest->_mp_size = bl;
483    res->s = 0;
484  }
485  else
486  {
487    al = dest->_mp_size = size+e;
488    if (al<2) al = 2;
489    dd = (mp_ptr)omAlloc(sizeof(mp_limb_t)*al);
490    for (i=0;i<size;i++) dd[i+e] = qp[i];
491    for (i=0;i<e;i++) dd[i] = 0;
492    res->s = 3;
493  }
494
495  dest->_mp_d = dd;
496  dest->_mp_alloc = al;
497  if (negative) dest->_mp_size = -dest->_mp_size;
498
499  if (res->s==0)
500    nlNormalize(res,dst);
501  else if (mpz_size1(res->z)<=MP_SMALL)
502  {
503    // res is new, res->ref is 1
504    res=nlShort3(res);
505  }
506  nlTest(res, dst);
507  return res;
508}
509
510//static number nlMapLongR(number from)
511//{
512//  gmp_float *ff=(gmp_float*)from;
513//  const mpf_t *f=ff->mpfp();
514//  int f_size=ABS((*f)[0]._mp_size);
515//  if (f_size==0)
516//    return nlInit(0);
517//  int f_sign=1;
518//  number work=ngcCopy(from);
519//  if (!ngcGreaterZero(work))
520//  {
521//    f_sign=-1;
522//    work=ngcNeg(work);
523//  }
524//  int i=0;
525//  mpz_t h1;
526//  mpz_init_set_ui(h1,1);
527//  while((FLT_RADIX*f) < DBL_MAX && i<DBL_MANT_DIG)
528//  {
529//    f*=FLT_RADIX;
530//    mpz_mul_ui(h1,h1,FLT_RADIX);
531//    i++;
532//  }
533//  number r=nlRInit(1);
534//  mpz_set_d(&(r->z),f);
535//  memcpy(&(r->n),&h1,sizeof(h1));
536//  r->s=0; /* not normalized */
537//  nlNormalize(r);
538//  return r;
539//
540//
541//  number r=nlRInit(1);
542//  int f_shift=f_size+(*f)[0]._mp_exp;
543//  if ( f_shift > 0)
544//  {
545//    r->s=0;
546//    mpz_init(&r->n);
547//    mpz_setbit(&r->n,f_shift*BYTES_PER_MP_LIMB*8);
548//    mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
549//    // now r->z has enough space
550//    memcpy(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
551//    nlNormalize(r);
552//  }
553//  else
554//  {
555//    r->s=3;
556//    if (f_shift==0)
557//    {
558//      mpz_setbit(&r->z,f_size*BYTES_PER_MP_LIMB*8-1);
559//      // now r->z has enough space
560//      memcpy(mpz_limb_d(&r->z),((*f)[0]._mp_d),f_size*BYTES_PER_MP_LIMB);
561//    }
562//    else /* f_shift < 0 */
563//    {
564//      mpz_setbit(&r->z,(f_size-f_shift)*BYTES_PER_MP_LIMB*8-1);
565//      // now r->z has enough space
566//      memcpy(mpz_limb_d(&r->z)-f_shift,((*f)[0]._mp_d),
567//        f_size*BYTES_PER_MP_LIMB);
568//    }
569//  }
570//  if ((*f)[0]._mp_size<0);
571//    r=nlNeg(r);
572//  return r;
573//}
574
575int nlSize(number a, const coeffs)
576{
577  if (a==INT_TO_SR(0))
578     return 0; /* rational 0*/
579  if (SR_HDL(a) & SR_INT)
580     return 1; /* immidiate int */
581  int s=a->z[0]._mp_alloc;
582//  while ((s>0) &&(a->z._mp_d[s]==0L)) s--;
583//#if SIZEOF_LONG == 8
584//  if (a->z._mp_d[s] < (unsigned long)0x100000000L) s=s*2-1;
585//  else s *=2;
586//#endif
587//  s++;
588  if (a->s<2)
589  {
590    int d=a->n[0]._mp_alloc;
591//    while ((d>0) && (a->n._mp_d[d]==0L)) d--;
592//#if SIZEOF_LONG == 8
593//    if (a->n._mp_d[d] < (unsigned long)0x100000000L) d=d*2-1;
594//    else d *=2;
595//#endif
596    s+=d;
597  }
598  return s;
599}
600
601/*2
602* convert number to int
603*/
604long nlInt(number &i, const coeffs r)
605{
606  nlTest(i, r);
607  nlNormalize(i,r);
608  if (SR_HDL(i) & SR_INT)
609  {
610    return SR_TO_INT(i);
611  }
612  if (i->s==3)
613  {
614    if(mpz_size1(i->z)>MP_SMALL) return 0;
615    long ul=mpz_get_si(i->z);
616    if (mpz_cmp_si(i->z,ul)!=0) return 0;
617    return ul;
618  }
619  mpz_t tmp;
620  long ul;
621  mpz_init(tmp);
622  MPZ_DIV(tmp,i->z,i->n);
623  if(mpz_size1(tmp)>MP_SMALL) ul=0;
624  else
625  {
626    ul=mpz_get_si(tmp);
627    if (mpz_cmp_si(tmp,ul)!=0) ul=0;
628  }
629  mpz_clear(tmp);
630  return ul;
631}
632
633/*2
634* convert number to bigint
635*/
636number nlBigInt(number &i, const coeffs r)
637{
638  nlTest(i, r);
639  nlNormalize(i,r);
640  if (SR_HDL(i) & SR_INT) return (i);
641  if (i->s==3)
642  {
643    return nlCopy(i,r);
644  }
645  number tmp=nlRInit(1);
646  MPZ_DIV(tmp->z,i->z,i->n);
647  tmp=nlShort3(tmp);
648  return tmp;
649}
650
651/*
652* 1/a
653*/
654number nlInvers(number a, const coeffs r)
655{
656  nlTest(a, r);
657  number n;
658  if (SR_HDL(a) & SR_INT)
659  {
660    if ((a==INT_TO_SR(1L)) || (a==INT_TO_SR(-1L)))
661    {
662      return a;
663    }
664    if (nlIsZero(a,r))
665    {
666      WerrorS(nDivBy0);
667      return INT_TO_SR(0);
668    }
669    n=ALLOC_RNUMBER();
670#if defined(LDEBUG)
671    n->debug=123456;
672#endif
673    n->s=1;
674    if ((long)a>0L)
675    {
676      mpz_init_set_si(n->z,(long)1);
677      mpz_init_set_si(n->n,(long)SR_TO_INT(a));
678    }
679    else
680    {
681      mpz_init_set_si(n->z,(long)-1);
682      mpz_init_set_si(n->n,(long)-SR_TO_INT(a));
683    }
684    nlTest(n, r);
685    return n;
686  }
687  n=ALLOC_RNUMBER();
688#if defined(LDEBUG)
689  n->debug=123456;
690#endif
691  {
692    n->s=a->s;
693    mpz_init_set(n->n,a->z);
694    switch (a->s)
695    {
696      case 0:
697      case 1:
698              mpz_init_set(n->z,a->n);
699              if (mpz_isNeg(n->n)) /* && n->s<2*/
700              {
701                mpz_neg(n->z,n->z);
702                mpz_neg(n->n,n->n);
703              }
704              if (mpz_cmp_si(n->n,(long)1)==0)
705              {
706                mpz_clear(n->n);
707                n->s=3;
708                n=nlShort3(n);
709              }
710              break;
711      case 3:
712              n->s=1;
713              if (mpz_isNeg(n->n)) /* && n->s<2*/
714              {
715                mpz_neg(n->n,n->n);
716                mpz_init_set_si(n->z,(long)-1);
717              }
718              else
719              {
720                mpz_init_set_si(n->z,(long)1);
721              }
722              break;
723    }
724  }
725  nlTest(n, r);
726  return n;
727}
728
729
730/*2
731* u := a / b in Z, if b | a (else undefined)
732*/
733number   nlExactDiv(number a, number b, const coeffs r)
734{
735  if (b==INT_TO_SR(0))
736  {
737    WerrorS(nDivBy0);
738    return INT_TO_SR(0);
739  }
740  if (a==INT_TO_SR(0))
741    return INT_TO_SR(0);
742  number u;
743  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
744  {
745    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
746    if ((a==INT_TO_SR(-(POW_2_28)))&&(b==INT_TO_SR(-1L)))
747    {
748      return nlRInit(POW_2_28);
749    }
750    long aa=SR_TO_INT(a);
751    long bb=SR_TO_INT(b);
752    return INT_TO_SR(aa/bb);
753  }
754  number bb=NULL;
755  if (SR_HDL(b) & SR_INT)
756  {
757    bb=nlRInit(SR_TO_INT(b));
758    b=bb;
759  }
760  u=ALLOC_RNUMBER();
761#if defined(LDEBUG)
762  u->debug=123456;
763#endif
764  mpz_init(u->z);
765  /* u=a/b */
766  u->s = 3;
767  MPZ_EXACTDIV(u->z,a->z,b->z);
768  if (bb!=NULL)
769  {
770    mpz_clear(bb->z);
771#if defined(LDEBUG)
772    bb->debug=654324;
773#endif
774    FREE_RNUMBER(bb); // omFreeBin((void *)bb, rnumber_bin);
775  }
776  u=nlShort3(u);
777  nlTest(u, r);
778  return u;
779}
780
781/*2
782* u := a / b in Z
783*/
784number nlIntDiv (number a, number b, const coeffs r)
785{
786  if (b==INT_TO_SR(0))
787  {
788    WerrorS(nDivBy0);
789    return INT_TO_SR(0);
790  }
791  if (a==INT_TO_SR(0))
792    return INT_TO_SR(0);
793  number u;
794  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
795  {
796    /* the small int -(1<<28) divided by -1 is the large int (1<<28)   */
797    if ((a==INT_TO_SR(-(POW_2_28)))&&(b==INT_TO_SR(-1L)))
798    {
799      return nlRInit(POW_2_28);
800    }
801    long aa=SR_TO_INT(a);
802    long bb=SR_TO_INT(b);
803    return INT_TO_SR(aa/bb);
804  }
805  if (SR_HDL(a) & SR_INT)
806  {
807    /* the small int -(1<<28) divided by 2^28 is 1   */
808    if (a==INT_TO_SR(-(POW_2_28)))
809    {
810      if(mpz_cmp_si(b->z,(POW_2_28))==0)
811      {
812        return INT_TO_SR(-1);
813      }
814    }
815    /* a is a small and b is a large int: -> 0 */
816    return INT_TO_SR(0);
817  }
818  number bb=NULL;
819  if (SR_HDL(b) & SR_INT)
820  {
821    bb=nlRInit(SR_TO_INT(b));
822    b=bb;
823  }
824  u=ALLOC_RNUMBER();
825#if defined(LDEBUG)
826  u->debug=123456;
827#endif
828  assume(a->s==3);
829  assume(b->s==3);
830  mpz_init_set(u->z,a->z);
831  /* u=u/b */
832  u->s = 3;
833  MPZ_DIV(u->z,u->z,b->z);
834  if (bb!=NULL)
835  {
836    mpz_clear(bb->z);
837#if defined(LDEBUG)
838    bb->debug=654324;
839#endif
840    FREE_RNUMBER(bb);
841  }
842  u=nlShort3(u);
843  nlTest(u,r);
844  return u;
845}
846
847/*2
848* u := a mod b in Z, u>=0
849*/
850number nlIntMod (number a, number b, const coeffs r)
851{
852  if (b==INT_TO_SR(0))
853  {
854    WerrorS(nDivBy0);
855    return INT_TO_SR(0);
856  }
857  if (a==INT_TO_SR(0))
858    return INT_TO_SR(0);
859  number u;
860  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
861  {
862    LONG bb=SR_TO_INT(b);
863    LONG c=SR_TO_INT(a) % bb;
864    return INT_TO_SR(c);
865  }
866  if (SR_HDL(a) & SR_INT)
867  {
868    mpz_t aa;
869    mpz_init(aa);
870    mpz_set_si(aa, SR_TO_INT(a));
871    u=ALLOC_RNUMBER();
872#if defined(LDEBUG)
873    u->debug=123456;
874#endif
875    u->s = 3;
876    mpz_init(u->z);
877    mpz_mod(u->z,aa,b->z);
878    mpz_clear(aa);
879    u=nlShort3(u);
880    nlTest(u,r);
881    return u;
882  }
883  number bb=NULL;
884  if (SR_HDL(b) & SR_INT)
885  {
886    bb=nlRInit(SR_TO_INT(b));
887    b=bb;
888  }
889  u=ALLOC_RNUMBER();
890#if defined(LDEBUG)
891  u->debug=123456;
892#endif
893  mpz_init(u->z);
894  u->s = 3;
895  mpz_mod(u->z,a->z,b->z);
896  if (bb!=NULL)
897  {
898    mpz_clear(bb->z);
899#if defined(LDEBUG)
900    bb->debug=654324;
901#endif
902    FREE_RNUMBER(bb);
903  }
904  u=nlShort3(u);
905  nlTest(u,r);
906  return u;
907}
908
909BOOLEAN nlDivBy (number a,number b, const coeffs)
910{
911  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
912  {
913    return ((SR_TO_INT(a) % SR_TO_INT(b))==0);
914  }
915  if (SR_HDL(b) & SR_INT)
916  {
917    return (mpz_divisible_ui_p(a->z,SR_TO_INT(b))!=0);
918  }
919  if (SR_HDL(a) & SR_INT) return FALSE;
920  return mpz_divisible_p(a->z, b->z) != 0;
921}
922
923int nlDivComp(number a, number b, const coeffs r)
924{
925  if (nlDivBy(a, b, r))
926  {
927    if (nlDivBy(b, a, r)) return 2;
928    return -1;
929  }
930  if (nlDivBy(b, a, r)) return 1;
931  return 0;
932}
933
934number  nlGetUnit (number n, const coeffs r)
935{
936  if (nlGreaterZero(n, r))
937    return INT_TO_SR(1);
938  else
939    return INT_TO_SR(-1);
940}
941
942coeffs nlQuot1(number c, const coeffs r)
943{
944  long ch = r->cfInt(c, r);
945  mpz_ptr dummy;
946  dummy = (mpz_ptr) omAlloc(sizeof(mpz_t));
947  mpz_init_set_ui(dummy, ch);
948  ZnmInfo info;
949  info.base = dummy;
950  info.exp = (unsigned long) 1;
951  coeffs rr = nInitChar(n_Zn, (void*)&info);
952  return(rr);
953}
954
955
956BOOLEAN nlIsUnit (number a, const coeffs)
957{
958  return ((SR_HDL(a) & SR_INT) && (ABS(SR_TO_INT(a))==1));
959}
960
961
962/*2
963* u := a / b
964*/
965number nlDiv (number a, number b, const coeffs r)
966{
967  if (nlIsZero(b,r))
968  {
969    WerrorS(nDivBy0);
970    return INT_TO_SR(0);
971  }
972  number u;
973// ---------- short / short ------------------------------------
974  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
975  {
976    LONG i=SR_TO_INT(a);
977    LONG j=SR_TO_INT(b);
978    if (j==1L) return a;
979    if ((i==-POW_2_28) && (j== -1L))
980    {
981      return nlRInit(POW_2_28);
982    }
983    LONG r=i%j;
984    if (r==0)
985    {
986      return INT_TO_SR(i/j);
987    }
988    u=ALLOC_RNUMBER();
989    u->s=0;
990    #if defined(LDEBUG)
991    u->debug=123456;
992    #endif
993    mpz_init_set_si(u->z,(long)i);
994    mpz_init_set_si(u->n,(long)j);
995  }
996  else
997  {
998    u=ALLOC_RNUMBER();
999    u->s=0;
1000    #if defined(LDEBUG)
1001    u->debug=123456;
1002    #endif
1003    mpz_init(u->z);
1004// ---------- short / long ------------------------------------
1005    if (SR_HDL(a) & SR_INT)
1006    {
1007      // short a / (z/n) -> (a*n)/z
1008      if (b->s<2)
1009      {
1010        mpz_mul_si(u->z,b->n,SR_TO_INT(a));
1011      }
1012      else
1013      // short a / long z -> a/z
1014      {
1015        mpz_set_si(u->z,SR_TO_INT(a));
1016      }
1017      if (mpz_cmp(u->z,b->z)==0)
1018      {
1019        mpz_clear(u->z);
1020        FREE_RNUMBER(u);
1021        return INT_TO_SR(1);
1022      }
1023      mpz_init_set(u->n,b->z);
1024    }
1025// ---------- long / short ------------------------------------
1026    else if (SR_HDL(b) & SR_INT)
1027    {
1028      mpz_set(u->z,a->z);
1029      // (z/n) / b -> z/(n*b)
1030      if (a->s<2)
1031      {
1032        mpz_init_set(u->n,a->n);
1033        if ((long)b>0L)
1034          mpz_mul_ui(u->n,u->n,SR_TO_INT(b));
1035        else
1036        {
1037          mpz_mul_ui(u->n,u->n,-SR_TO_INT(b));
1038          mpz_neg(u->z,u->z);
1039        }
1040      }
1041      else
1042      // long z / short b -> z/b
1043      {
1044        //mpz_set(u->z,a->z);
1045        mpz_init_set_si(u->n,SR_TO_INT(b));
1046      }
1047    }
1048// ---------- long / long ------------------------------------
1049    else
1050    {
1051      mpz_set(u->z,a->z);
1052      mpz_init_set(u->n,b->z);
1053      if (a->s<2) mpz_mul(u->n,u->n,a->n);
1054      if (b->s<2) mpz_mul(u->z,u->z,b->n);
1055    }
1056  }
1057  if (mpz_isNeg(u->n))
1058  {
1059    mpz_neg(u->z,u->z);
1060    mpz_neg(u->n,u->n);
1061  }
1062  if (mpz_cmp_si(u->n,(long)1)==0)
1063  {
1064    mpz_clear(u->n);
1065    u->s=3;
1066    u=nlShort3(u);
1067  }
1068  nlTest(u, r);
1069  return u;
1070}
1071
1072/*2
1073* u:= x ^ exp
1074*/
1075void nlPower (number x,int exp,number * u, const coeffs r)
1076{
1077  *u = INT_TO_SR(0); // 0^e, e!=0
1078  if (exp==0)
1079    *u= INT_TO_SR(1);
1080  else if (!nlIsZero(x,r))
1081  {
1082    nlTest(x, r);
1083    number aa=NULL;
1084    if (SR_HDL(x) & SR_INT)
1085    {
1086      aa=nlRInit(SR_TO_INT(x));
1087      x=aa;
1088    }
1089    else if (x->s==0)
1090      nlNormalize(x,r);
1091    *u=ALLOC_RNUMBER();
1092#if defined(LDEBUG)
1093    (*u)->debug=123456;
1094#endif
1095    mpz_init((*u)->z);
1096    mpz_pow_ui((*u)->z,x->z,(unsigned long)exp);
1097    if (x->s<2)
1098    {
1099      if (mpz_cmp_si(x->n,(long)1)==0)
1100      {
1101        x->s=3;
1102        mpz_clear(x->n);
1103      }
1104      else
1105      {
1106        mpz_init((*u)->n);
1107        mpz_pow_ui((*u)->n,x->n,(unsigned long)exp);
1108      }
1109    }
1110    (*u)->s = x->s;
1111    if ((*u)->s==3) *u=nlShort3(*u);
1112    if (aa!=NULL)
1113    {
1114      mpz_clear(aa->z);
1115      FREE_RNUMBER(aa);
1116    }
1117  }
1118#ifdef LDEBUG
1119  if (exp<0) Print("nlPower: neg. exp. %d\n",exp);
1120  nlTest(*u, r);
1121#endif
1122}
1123
1124
1125/*2
1126* za >= 0 ?
1127*/
1128BOOLEAN nlGreaterZero (number a, const coeffs r)
1129{
1130  nlTest(a, r);
1131  if (SR_HDL(a) & SR_INT) return SR_HDL(a)>1L /* represents number(0) */;
1132  return (!mpz_isNeg(a->z));
1133}
1134
1135/*2
1136* a > b ?
1137*/
1138BOOLEAN nlGreater (number a, number b, const coeffs r)
1139{
1140  nlTest(a, r);
1141  nlTest(b, r);
1142  number re;
1143  BOOLEAN rr;
1144  re=nlSub(a,b,r);
1145  rr=(!nlIsZero(re,r)) && (nlGreaterZero(re,r));
1146  nlDelete(&re,r);
1147  return rr;
1148}
1149
1150/*2
1151* a == -1 ?
1152*/
1153BOOLEAN nlIsMOne (number a, const coeffs r)
1154{
1155#ifdef LDEBUG
1156  if (a==NULL) return FALSE;
1157  nlTest(a, r);
1158#endif
1159  return  (a==INT_TO_SR(-1L));
1160}
1161
1162/*2
1163* result =gcd(a,b)
1164*/
1165number nlGcd(number a, number b, const coeffs r)
1166{
1167  number result;
1168  nlTest(a, r);
1169  nlTest(b, r);
1170  //nlNormalize(a);
1171  //nlNormalize(b);
1172  if ((a==INT_TO_SR(1L))||(a==INT_TO_SR(-1L))
1173  ||  (b==INT_TO_SR(1L))||(b==INT_TO_SR(-1L)))
1174    return INT_TO_SR(1L);
1175  if (a==INT_TO_SR(0)) /* gcd(0,b) ->b */
1176    return nlCopy(b,r);
1177  if (b==INT_TO_SR(0)) /* gcd(a,0) -> a */
1178    return nlCopy(a,r);
1179  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
1180  {
1181    long i=SR_TO_INT(a);
1182    long j=SR_TO_INT(b);
1183    if((i==0L)||(j==0L))
1184      return INT_TO_SR(1);
1185    long l;
1186    i=ABS(i);
1187    j=ABS(j);
1188    do
1189    {
1190      l=i%j;
1191      i=j;
1192      j=l;
1193    } while (l!=0L);
1194    if (i==POW_2_28)
1195      result=nlRInit(POW_2_28);
1196    else
1197     result=INT_TO_SR(i);
1198    nlTest(result,r);
1199    return result;
1200  }
1201  if (((!(SR_HDL(a) & SR_INT))&&(a->s<2))
1202  ||  ((!(SR_HDL(b) & SR_INT))&&(b->s<2))) return INT_TO_SR(1);
1203  if (SR_HDL(a) & SR_INT)
1204  {
1205    LONG aa=ABS(SR_TO_INT(a));
1206    unsigned long t=mpz_gcd_ui(NULL,b->z,(long)aa);
1207    if (t==POW_2_28)
1208      result=nlRInit(POW_2_28);
1209    else
1210     result=INT_TO_SR(t);
1211  }
1212  else
1213  if (SR_HDL(b) & SR_INT)
1214  {
1215    LONG bb=ABS(SR_TO_INT(b));
1216    unsigned long t=mpz_gcd_ui(NULL,a->z,(long)bb);
1217    if (t==POW_2_28)
1218      result=nlRInit(POW_2_28);
1219    else
1220     result=INT_TO_SR(t);
1221  }
1222  else
1223  {
1224    result=ALLOC0_RNUMBER();
1225    mpz_init(result->z);
1226    mpz_gcd(result->z,a->z,b->z);
1227    result->s = 3;
1228  #ifdef LDEBUG
1229    result->debug=123456;
1230  #endif
1231    result=nlShort3(result);
1232  }
1233  nlTest(result, r);
1234  return result;
1235}
1236//number nlGcd_dummy(number a, number b, const coeffs r)
1237//{
1238//  extern char my_yylinebuf[80];
1239//  Print("nlGcd in >>%s<<\n",my_yylinebuf);
1240//  return nlGcd(a,b,r);;
1241//}
1242
1243number nlShort1(number x) // assume x->s==0/1
1244{
1245  assume(x->s<2);
1246  if (mpz_cmp_ui(x->z,(long)0)==0)
1247  {
1248    _nlDelete_NoImm(&x);
1249    return INT_TO_SR(0);
1250  }
1251  if (x->s<2)
1252  {
1253    if (mpz_cmp(x->z,x->n)==0)
1254    {
1255      _nlDelete_NoImm(&x);
1256      return INT_TO_SR(1);
1257    }
1258  }
1259  return x;
1260}
1261/*2
1262* simplify x
1263*/
1264void nlNormalize (number &x, const coeffs r)
1265{
1266  if ((SR_HDL(x) & SR_INT) ||(x==NULL))
1267    return;
1268  if (x->s==3)
1269  {
1270    x=nlShort3_noinline(x);
1271    nlTest(x,r);
1272    return;
1273  }
1274  else if (x->s==0)
1275  {
1276    if (mpz_cmp_si(x->n,(long)1)==0)
1277    {
1278      mpz_clear(x->n);
1279      x->s=3;
1280      x=nlShort3(x);
1281    }
1282    else
1283    {
1284      mpz_t gcd;
1285      mpz_init(gcd);
1286      mpz_gcd(gcd,x->z,x->n);
1287      x->s=1;
1288      if (mpz_cmp_si(gcd,(long)1)!=0)
1289      {
1290        MPZ_EXACTDIV(x->z,x->z,gcd);
1291        MPZ_EXACTDIV(x->n,x->n,gcd);
1292        if (mpz_cmp_si(x->n,(long)1)==0)
1293        {
1294          mpz_clear(x->n);
1295          x->s=3;
1296          x=nlShort3_noinline(x);
1297        }
1298      }
1299      mpz_clear(gcd);
1300    }
1301  }
1302  nlTest(x, r);
1303}
1304
1305/*2
1306* returns in result->z the lcm(a->z,b->n)
1307*/
1308number nlNormalizeHelper(number a, number b, const coeffs r)
1309{
1310  number result;
1311  nlTest(a, r);
1312  nlTest(b, r);
1313  if ((SR_HDL(b) & SR_INT)
1314  || (b->s==3))
1315  {
1316    // b is 1/(b->n) => b->n is 1 => result is a
1317    return nlCopy(a,r);
1318  }
1319  result=ALLOC_RNUMBER();
1320#if defined(LDEBUG)
1321  result->debug=123456;
1322#endif
1323  result->s=3;
1324  mpz_t gcd;
1325  mpz_init(gcd);
1326  mpz_init(result->z);
1327  if (SR_HDL(a) & SR_INT)
1328    mpz_gcd_ui(gcd,b->n,ABS(SR_TO_INT(a)));
1329  else
1330    mpz_gcd(gcd,a->z,b->n);
1331  if (mpz_cmp_si(gcd,(long)1)!=0)
1332  {
1333    mpz_t bt;
1334    mpz_init_set(bt,b->n);
1335    MPZ_EXACTDIV(bt,bt,gcd);
1336    if (SR_HDL(a) & SR_INT)
1337      mpz_mul_si(result->z,bt,SR_TO_INT(a));
1338    else
1339      mpz_mul(result->z,bt,a->z);
1340    mpz_clear(bt);
1341  }
1342  else
1343    if (SR_HDL(a) & SR_INT)
1344      mpz_mul_si(result->z,b->n,SR_TO_INT(a));
1345    else
1346      mpz_mul(result->z,b->n,a->z);
1347  mpz_clear(gcd);
1348  result=nlShort3(result);
1349  nlTest(result, r);
1350  return result;
1351}
1352
1353// Map q \in QQ or ZZ \to Zp or an extension of it
1354// src = Q or Z, dst = Zp (or an extension of Zp)
1355number nlModP(number q, const coeffs Q, const coeffs Zp)
1356{
1357  const int p = n_GetChar(Zp);
1358  assume( p > 0 );
1359
1360  const long P = p;
1361  assume( P > 0 );
1362
1363  // embedded long within q => only long numerator has to be converted
1364  // to int (modulo char.)
1365  if (SR_HDL(q) & SR_INT)
1366  {
1367    long i = SR_TO_INT(q);
1368    return n_Init( i, Zp );
1369  }
1370
1371  const unsigned long PP = p;
1372
1373  // numerator modulo char. should fit into int
1374  number z = n_Init( static_cast<long>(mpz_fdiv_ui(q->z, PP)), Zp );
1375
1376  // denominator != 1?
1377  if (q->s!=3)
1378  {
1379    // denominator modulo char. should fit into int
1380    number n = n_Init( static_cast<long>(mpz_fdiv_ui(q->n, PP)), Zp );
1381
1382    number res = n_Div( z, n, Zp );
1383
1384    n_Delete(&z, Zp);
1385    n_Delete(&n, Zp);
1386
1387    return res;
1388  }
1389
1390  return z;
1391}
1392
1393#ifdef HAVE_RINGS
1394/*2
1395* convert number i (from Q) to GMP and warn if denom != 1
1396*/
1397void nlGMP(number &i, number n, const coeffs r)
1398{
1399  // Hier brauche ich einfach die GMP Zahl
1400  nlTest(i, r);
1401  nlNormalize(i, r);
1402  if (SR_HDL(i) & SR_INT)
1403  {
1404    mpz_set_si((mpz_ptr) n, SR_TO_INT(i));
1405    return;
1406  }
1407  if (i->s!=3)
1408  {
1409     WarnS("Omitted denominator during coefficient mapping !");
1410  }
1411  mpz_set((mpz_ptr) n, i->z);
1412}
1413#endif
1414
1415/*2
1416* acces to denominator, other 1 for integers
1417*/
1418number   nlGetDenom(number &n, const coeffs r)
1419{
1420  if (!(SR_HDL(n) & SR_INT))
1421  {
1422    if (n->s==0)
1423    {
1424      nlNormalize(n,r);
1425    }
1426    if (!(SR_HDL(n) & SR_INT))
1427    {
1428      if (n->s!=3)
1429      {
1430        number u=ALLOC_RNUMBER();
1431        u->s=3;
1432#if defined(LDEBUG)
1433        u->debug=123456;
1434#endif
1435        mpz_init_set(u->z,n->n);
1436        u=nlShort3_noinline(u);
1437        return u;
1438      }
1439    }
1440  }
1441  return INT_TO_SR(1);
1442}
1443
1444/*2
1445* acces to Nominator, nlCopy(n) for integers
1446*/
1447number   nlGetNumerator(number &n, const coeffs r)
1448{
1449  if (!(SR_HDL(n) & SR_INT))
1450  {
1451    if (n->s==0)
1452    {
1453      nlNormalize(n,r);
1454    }
1455    if (!(SR_HDL(n) & SR_INT))
1456    {
1457      number u=ALLOC_RNUMBER();
1458#if defined(LDEBUG)
1459      u->debug=123456;
1460#endif
1461      u->s=3;
1462      mpz_init_set(u->z,n->z);
1463      if (n->s!=3)
1464      {
1465        u=nlShort3_noinline(u);
1466      }
1467      return u;
1468    }
1469  }
1470  return n; // imm. int
1471}
1472
1473/***************************************************************
1474 *
1475 * routines which are needed by Inline(d) routines
1476 *
1477 *******************************************************************/
1478BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b)
1479{
1480  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
1481//  long - short
1482  BOOLEAN bo;
1483  if (SR_HDL(b) & SR_INT)
1484  {
1485    if (a->s!=0) return FALSE;
1486    number n=b; b=a; a=n;
1487  }
1488//  short - long
1489  if (SR_HDL(a) & SR_INT)
1490  {
1491    if (b->s!=0)
1492      return FALSE;
1493    if (((long)a > 0L) && (mpz_isNeg(b->z)))
1494      return FALSE;
1495    if (((long)a < 0L) && (!mpz_isNeg(b->z)))
1496      return FALSE;
1497    mpz_t  bb;
1498    mpz_init_set(bb,b->n);
1499    mpz_mul_si(bb,bb,(long)SR_TO_INT(a));
1500    bo=(mpz_cmp(bb,b->z)==0);
1501    mpz_clear(bb);
1502    return bo;
1503  }
1504// long - long
1505  if (((a->s==1) && (b->s==3))
1506  ||  ((b->s==1) && (a->s==3)))
1507    return FALSE;
1508  if (mpz_isNeg(a->z)&&(!mpz_isNeg(b->z)))
1509    return FALSE;
1510  if (mpz_isNeg(b->z)&&(!mpz_isNeg(a->z)))
1511    return FALSE;
1512  mpz_t  aa;
1513  mpz_t  bb;
1514  mpz_init_set(aa,a->z);
1515  mpz_init_set(bb,b->z);
1516  if (a->s<2) mpz_mul(bb,bb,a->n);
1517  if (b->s<2) mpz_mul(aa,aa,b->n);
1518  bo=(mpz_cmp(aa,bb)==0);
1519  mpz_clear(aa);
1520  mpz_clear(bb);
1521  return bo;
1522}
1523
1524// copy not immediate number a
1525number _nlCopy_NoImm(number a)
1526{
1527  assume(!((SR_HDL(a) & SR_INT)||(a==NULL)));
1528  //nlTest(a, r);
1529  number b=ALLOC_RNUMBER();
1530#if defined(LDEBUG)
1531  b->debug=123456;
1532#endif
1533  switch (a->s)
1534  {
1535    case 0:
1536    case 1:
1537            mpz_init_set(b->n,a->n);
1538    case 3:
1539            mpz_init_set(b->z,a->z);
1540            break;
1541  }
1542  b->s = a->s;
1543  return b;
1544}
1545
1546void _nlDelete_NoImm(number *a)
1547{
1548  {
1549    switch ((*a)->s)
1550    {
1551      case 0:
1552      case 1:
1553        mpz_clear((*a)->n);
1554      case 3:
1555        mpz_clear((*a)->z);
1556#ifdef LDEBUG
1557        (*a)->s=2;
1558#endif
1559    }
1560    FREE_RNUMBER(*a); // omFreeBin((void *) *a, rnumber_bin);
1561  }
1562}
1563
1564number _nlNeg_NoImm(number a)
1565{
1566  {
1567    mpz_neg(a->z,a->z);
1568    if (a->s==3)
1569    {
1570      a=nlShort3(a);
1571    }
1572  }
1573  return a;
1574}
1575
1576number _nlAdd_aNoImm_OR_bNoImm(number a, number b)
1577{
1578  number u=ALLOC_RNUMBER();
1579#if defined(LDEBUG)
1580  u->debug=123456;
1581#endif
1582  mpz_init(u->z);
1583  if (SR_HDL(b) & SR_INT)
1584  {
1585    number x=a;
1586    a=b;
1587    b=x;
1588  }
1589  if (SR_HDL(a) & SR_INT)
1590  {
1591    switch (b->s)
1592    {
1593      case 0:
1594      case 1:/* a:short, b:1 */
1595      {
1596        mpz_t x;
1597        mpz_init(x);
1598        mpz_mul_si(x,b->n,SR_TO_INT(a));
1599        mpz_add(u->z,b->z,x);
1600        mpz_clear(x);
1601        if (mpz_cmp_ui(u->z,(long)0)==0)
1602        {
1603          mpz_clear(u->z);
1604          FREE_RNUMBER(u);
1605          return INT_TO_SR(0);
1606        }
1607        if (mpz_cmp(u->z,b->n)==0)
1608        {
1609          mpz_clear(u->z);
1610          FREE_RNUMBER(u);
1611          return INT_TO_SR(1);
1612        }
1613        mpz_init_set(u->n,b->n);
1614        u->s = 0;
1615        break;
1616      }
1617      case 3:
1618      {
1619        if ((long)a>0L)
1620          mpz_add_ui(u->z,b->z,SR_TO_INT(a));
1621        else
1622          mpz_sub_ui(u->z,b->z,-SR_TO_INT(a));
1623        if (mpz_cmp_ui(u->z,(long)0)==0)
1624        {
1625          mpz_clear(u->z);
1626          FREE_RNUMBER(u);
1627          return INT_TO_SR(0);
1628        }
1629        u->s = 3;
1630        u=nlShort3(u);
1631        break;
1632      }
1633    }
1634  }
1635  else
1636  {
1637    switch (a->s)
1638    {
1639      case 0:
1640      case 1:
1641      {
1642        switch(b->s)
1643        {
1644          case 0:
1645          case 1:
1646          {
1647            mpz_t x;
1648            mpz_init(x);
1649
1650            mpz_mul(x,b->z,a->n);
1651            mpz_mul(u->z,a->z,b->n);
1652            mpz_add(u->z,u->z,x);
1653            mpz_clear(x);
1654
1655            if (mpz_cmp_ui(u->z,(long)0)==0)
1656            {
1657              mpz_clear(u->z);
1658              FREE_RNUMBER(u);
1659              return INT_TO_SR(0);
1660            }
1661            mpz_init(u->n);
1662            mpz_mul(u->n,a->n,b->n);
1663            if (mpz_cmp(u->z,u->n)==0)
1664            {
1665               mpz_clear(u->z);
1666               mpz_clear(u->n);
1667               FREE_RNUMBER(u);
1668               return INT_TO_SR(1);
1669            }
1670            u->s = 0;
1671            break;
1672          }
1673          case 3: /* a:1 b:3 */
1674          {
1675            mpz_mul(u->z,b->z,a->n);
1676            mpz_add(u->z,u->z,a->z);
1677            if (mpz_cmp_ui(u->z,(long)0)==0)
1678            {
1679              mpz_clear(u->z);
1680              FREE_RNUMBER(u);
1681              return INT_TO_SR(0);
1682            }
1683            if (mpz_cmp(u->z,a->n)==0)
1684            {
1685              mpz_clear(u->z);
1686              FREE_RNUMBER(u);
1687              return INT_TO_SR(1);
1688            }
1689            mpz_init_set(u->n,a->n);
1690            u->s = 0;
1691            break;
1692          }
1693        } /*switch (b->s) */
1694        break;
1695      }
1696      case 3:
1697      {
1698        switch(b->s)
1699        {
1700          case 0:
1701          case 1:/* a:3, b:1 */
1702          {
1703            mpz_mul(u->z,a->z,b->n);
1704            mpz_add(u->z,u->z,b->z);
1705            if (mpz_cmp_ui(u->z,(long)0)==0)
1706            {
1707              mpz_clear(u->z);
1708              FREE_RNUMBER(u);
1709              return INT_TO_SR(0);
1710            }
1711            if (mpz_cmp(u->z,b->n)==0)
1712            {
1713              mpz_clear(u->z);
1714              FREE_RNUMBER(u);
1715              return INT_TO_SR(1);
1716            }
1717            mpz_init_set(u->n,b->n);
1718            u->s = 0;
1719            break;
1720          }
1721          case 3:
1722          {
1723            mpz_add(u->z,a->z,b->z);
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        break;
1736      }
1737    }
1738  }
1739  return u;
1740}
1741
1742void _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b)
1743{
1744  if (SR_HDL(b) & SR_INT)
1745  {
1746    switch (a->s)
1747    {
1748      case 0:
1749      case 1:/* b:short, a:1 */
1750      {
1751        mpz_t x;
1752        mpz_init(x);
1753        mpz_mul_si(x,a->n,SR_TO_INT(b));
1754        mpz_add(a->z,a->z,x);
1755        mpz_clear(x);
1756        a->s = 0;
1757        a=nlShort1(a);
1758        break;
1759      }
1760      case 3:
1761      {
1762        if ((long)b>0L)
1763          mpz_add_ui(a->z,a->z,SR_TO_INT(b));
1764        else
1765          mpz_sub_ui(a->z,a->z,-SR_TO_INT(b));
1766        a->s = 3;
1767        a=nlShort3_noinline(a);
1768        break;
1769      }
1770    }
1771    return;
1772  }
1773  else if (SR_HDL(a) & SR_INT)
1774  {
1775    number u=ALLOC_RNUMBER();
1776    #if defined(LDEBUG)
1777    u->debug=123456;
1778    #endif
1779    mpz_init(u->z);
1780    switch (b->s)
1781    {
1782      case 0:
1783      case 1:/* a:short, b:1 */
1784      {
1785        mpz_t x;
1786        mpz_init(x);
1787
1788        mpz_mul_si(x,b->n,SR_TO_INT(a));
1789        mpz_add(u->z,b->z,x);
1790        mpz_clear(x);
1791        // result cannot be 0, if coeffs are normalized
1792        mpz_init_set(u->n,b->n);
1793        u->s = 0;
1794        u=nlShort1(u);
1795        break;
1796      }
1797      case 3:
1798      {
1799        if ((long)a>0L)
1800          mpz_add_ui(u->z,b->z,SR_TO_INT(a));
1801        else
1802          mpz_sub_ui(u->z,b->z,-SR_TO_INT(a));
1803        // result cannot be 0, if coeffs are normalized
1804        u->s = 3;
1805        u=nlShort3_noinline(u);
1806        break;
1807      }
1808    }
1809    a=u;
1810  }
1811  else
1812  {
1813    switch (a->s)
1814    {
1815      case 0:
1816      case 1:
1817      {
1818        switch(b->s)
1819        {
1820          case 0:
1821          case 1: /* a:1 b:1 */
1822          {
1823            mpz_t x;
1824            mpz_t y;
1825            mpz_init(x);
1826            mpz_init(y);
1827            mpz_mul(x,b->z,a->n);
1828            mpz_mul(y,a->z,b->n);
1829            mpz_add(a->z,x,y);
1830            mpz_clear(x);
1831            mpz_clear(y);
1832            mpz_mul(a->n,a->n,b->n);
1833            a->s = 0;
1834            break;
1835          }
1836          case 3: /* a:1 b:3 */
1837          {
1838            mpz_t x;
1839            mpz_init(x);
1840            mpz_mul(x,b->z,a->n);
1841            mpz_add(a->z,a->z,x);
1842            mpz_clear(x);
1843            a->s = 0;
1844            break;
1845          }
1846        } /*switch (b->s) */
1847        a=nlShort1(a);
1848        break;
1849      }
1850      case 3:
1851      {
1852        switch(b->s)
1853        {
1854          case 0:
1855          case 1:/* a:3, b:1 */
1856          {
1857            mpz_t x;
1858            mpz_init(x);
1859            mpz_mul(x,a->z,b->n);
1860            mpz_add(a->z,b->z,x);
1861            mpz_clear(x);
1862            mpz_init_set(a->n,b->n);
1863            a->s = 0;
1864            a=nlShort1(a);
1865            break;
1866          }
1867          case 3:
1868          {
1869            mpz_add(a->z,a->z,b->z);
1870            a->s = 3;
1871            a=nlShort3_noinline(a);
1872            break;
1873          }
1874        }
1875        break;
1876      }
1877    }
1878  }
1879}
1880
1881number _nlSub_aNoImm_OR_bNoImm(number a, number b)
1882{
1883  number u=ALLOC_RNUMBER();
1884#if defined(LDEBUG)
1885  u->debug=123456;
1886#endif
1887  mpz_init(u->z);
1888  if (SR_HDL(a) & SR_INT)
1889  {
1890    switch (b->s)
1891    {
1892      case 0:
1893      case 1:/* a:short, b:1 */
1894      {
1895        mpz_t x;
1896        mpz_init(x);
1897        mpz_mul_si(x,b->n,SR_TO_INT(a));
1898        mpz_sub(u->z,x,b->z);
1899        mpz_clear(x);
1900        if (mpz_cmp_ui(u->z,(long)0)==0)
1901        {
1902          mpz_clear(u->z);
1903          FREE_RNUMBER(u);
1904          return INT_TO_SR(0);
1905        }
1906        if (mpz_cmp(u->z,b->n)==0)
1907        {
1908          mpz_clear(u->z);
1909          FREE_RNUMBER(u);
1910          return INT_TO_SR(1);
1911        }
1912        mpz_init_set(u->n,b->n);
1913        u->s = 0;
1914        break;
1915      }
1916      case 3:
1917      {
1918        if ((long)a>0L)
1919        {
1920          mpz_sub_ui(u->z,b->z,SR_TO_INT(a));
1921          mpz_neg(u->z,u->z);
1922        }
1923        else
1924        {
1925          mpz_add_ui(u->z,b->z,-SR_TO_INT(a));
1926          mpz_neg(u->z,u->z);
1927        }
1928        if (mpz_cmp_ui(u->z,(long)0)==0)
1929        {
1930          mpz_clear(u->z);
1931          FREE_RNUMBER(u);
1932          return INT_TO_SR(0);
1933        }
1934        u->s = 3;
1935        u=nlShort3(u);
1936        break;
1937      }
1938    }
1939  }
1940  else if (SR_HDL(b) & SR_INT)
1941  {
1942    switch (a->s)
1943    {
1944      case 0:
1945      case 1:/* b:short, a:1 */
1946      {
1947        mpz_t x;
1948        mpz_init(x);
1949        mpz_mul_si(x,a->n,SR_TO_INT(b));
1950        mpz_sub(u->z,a->z,x);
1951        mpz_clear(x);
1952        if (mpz_cmp_ui(u->z,(long)0)==0)
1953        {
1954          mpz_clear(u->z);
1955          FREE_RNUMBER(u);
1956          return INT_TO_SR(0);
1957        }
1958        if (mpz_cmp(u->z,a->n)==0)
1959        {
1960          mpz_clear(u->z);
1961          FREE_RNUMBER(u);
1962          return INT_TO_SR(1);
1963        }
1964        mpz_init_set(u->n,a->n);
1965        u->s = 0;
1966        break;
1967      }
1968      case 3:
1969      {
1970        if ((long)b>0L)
1971        {
1972          mpz_sub_ui(u->z,a->z,SR_TO_INT(b));
1973        }
1974        else
1975        {
1976          mpz_add_ui(u->z,a->z,-SR_TO_INT(b));
1977        }
1978        if (mpz_cmp_ui(u->z,(long)0)==0)
1979        {
1980          mpz_clear(u->z);
1981          FREE_RNUMBER(u);
1982          return INT_TO_SR(0);
1983        }
1984        u->s = 3;
1985        u=nlShort3(u);
1986        break;
1987      }
1988    }
1989  }
1990  else
1991  {
1992    switch (a->s)
1993    {
1994      case 0:
1995      case 1:
1996      {
1997        switch(b->s)
1998        {
1999          case 0:
2000          case 1:
2001          {
2002            mpz_t x;
2003            mpz_t y;
2004            mpz_init(x);
2005            mpz_init(y);
2006            mpz_mul(x,b->z,a->n);
2007            mpz_mul(y,a->z,b->n);
2008            mpz_sub(u->z,y,x);
2009            mpz_clear(x);
2010            mpz_clear(y);
2011            if (mpz_cmp_ui(u->z,(long)0)==0)
2012            {
2013              mpz_clear(u->z);
2014              FREE_RNUMBER(u);
2015              return INT_TO_SR(0);
2016            }
2017            mpz_init(u->n);
2018            mpz_mul(u->n,a->n,b->n);
2019            if (mpz_cmp(u->z,u->n)==0)
2020            {
2021              mpz_clear(u->z);
2022              mpz_clear(u->n);
2023              FREE_RNUMBER(u);
2024              return INT_TO_SR(1);
2025            }
2026            u->s = 0;
2027            break;
2028          }
2029          case 3: /* a:1, b:3 */
2030          {
2031            mpz_t x;
2032            mpz_init(x);
2033            mpz_mul(x,b->z,a->n);
2034            mpz_sub(u->z,a->z,x);
2035            mpz_clear(x);
2036            if (mpz_cmp_ui(u->z,(long)0)==0)
2037            {
2038              mpz_clear(u->z);
2039              FREE_RNUMBER(u);
2040              return INT_TO_SR(0);
2041            }
2042            if (mpz_cmp(u->z,a->n)==0)
2043            {
2044              mpz_clear(u->z);
2045              FREE_RNUMBER(u);
2046              return INT_TO_SR(1);
2047            }
2048            mpz_init_set(u->n,a->n);
2049            u->s = 0;
2050            break;
2051          }
2052        }
2053        break;
2054      }
2055      case 3:
2056      {
2057        switch(b->s)
2058        {
2059          case 0:
2060          case 1: /* a:3, b:1 */
2061          {
2062            mpz_t x;
2063            mpz_init(x);
2064            mpz_mul(x,a->z,b->n);
2065            mpz_sub(u->z,x,b->z);
2066            mpz_clear(x);
2067            if (mpz_cmp_ui(u->z,(long)0)==0)
2068            {
2069              mpz_clear(u->z);
2070              FREE_RNUMBER(u);
2071              return INT_TO_SR(0);
2072            }
2073            if (mpz_cmp(u->z,b->n)==0)
2074            {
2075              mpz_clear(u->z);
2076              FREE_RNUMBER(u);
2077              return INT_TO_SR(1);
2078            }
2079            mpz_init_set(u->n,b->n);
2080            u->s = 0;
2081            break;
2082          }
2083          case 3: /* a:3 , b:3 */
2084          {
2085            mpz_sub(u->z,a->z,b->z);
2086            if (mpz_cmp_ui(u->z,(long)0)==0)
2087            {
2088              mpz_clear(u->z);
2089              FREE_RNUMBER(u);
2090              return INT_TO_SR(0);
2091            }
2092            u->s = 3;
2093            u=nlShort3(u);
2094            break;
2095          }
2096        }
2097        break;
2098      }
2099    }
2100  }
2101  return u;
2102}
2103
2104// a and b are intermediate, but a*b not
2105number _nlMult_aImm_bImm_rNoImm(number a, number b)
2106{
2107  number u=ALLOC_RNUMBER();
2108#if defined(LDEBUG)
2109  u->debug=123456;
2110#endif
2111  u->s=3;
2112  mpz_init_set_si(u->z,SR_TO_INT(a));
2113  mpz_mul_si(u->z,u->z,SR_TO_INT(b));
2114  return u;
2115}
2116
2117// a or b are not immediate
2118number _nlMult_aNoImm_OR_bNoImm(number a, number b)
2119{
2120  assume(! (SR_HDL(a) & SR_HDL(b) & SR_INT));
2121  number u=ALLOC_RNUMBER();
2122#if defined(LDEBUG)
2123  u->debug=123456;
2124#endif
2125  mpz_init(u->z);
2126  if (SR_HDL(b) & SR_INT)
2127  {
2128    number x=a;
2129    a=b;
2130    b=x;
2131  }
2132  if (SR_HDL(a) & SR_INT)
2133  {
2134    u->s=b->s;
2135    if (u->s==1) u->s=0;
2136    if ((long)a>0L)
2137    {
2138      mpz_mul_ui(u->z,b->z,(unsigned long)SR_TO_INT(a));
2139    }
2140    else
2141    {
2142      if (a==INT_TO_SR(-1))
2143      {
2144        mpz_set(u->z,b->z);
2145        mpz_neg(u->z,u->z);
2146        u->s=b->s;
2147      }
2148      else
2149      {
2150        mpz_mul_ui(u->z,b->z,(unsigned long)-SR_TO_INT(a));
2151        mpz_neg(u->z,u->z);
2152      }
2153    }
2154    if (u->s<2)
2155    {
2156      if (mpz_cmp(u->z,b->n)==0)
2157      {
2158        mpz_clear(u->z);
2159        FREE_RNUMBER(u);
2160        return INT_TO_SR(1);
2161      }
2162      mpz_init_set(u->n,b->n);
2163    }
2164    else //u->s==3
2165    {
2166      u=nlShort3(u);
2167    }
2168  }
2169  else
2170  {
2171    mpz_mul(u->z,a->z,b->z);
2172    u->s = 0;
2173    if(a->s==3)
2174    {
2175      if(b->s==3)
2176      {
2177        u->s = 3;
2178      }
2179      else
2180      {
2181        if (mpz_cmp(u->z,b->n)==0)
2182        {
2183          mpz_clear(u->z);
2184          FREE_RNUMBER(u);
2185          return INT_TO_SR(1);
2186        }
2187        mpz_init_set(u->n,b->n);
2188      }
2189    }
2190    else
2191    {
2192      if(b->s==3)
2193      {
2194        if (mpz_cmp(u->z,a->n)==0)
2195        {
2196          mpz_clear(u->z);
2197          FREE_RNUMBER(u);
2198          return INT_TO_SR(1);
2199        }
2200        mpz_init_set(u->n,a->n);
2201      }
2202      else
2203      {
2204        mpz_init(u->n);
2205        mpz_mul(u->n,a->n,b->n);
2206        if (mpz_cmp(u->z,u->n)==0)
2207        {
2208          mpz_clear(u->z);
2209          mpz_clear(u->n);
2210          FREE_RNUMBER(u);
2211          return INT_TO_SR(1);
2212        }
2213      }
2214    }
2215  }
2216  return u;
2217}
2218
2219/*2
2220* copy a to b for mapping
2221*/
2222number nlCopyMap(number a, const coeffs src, const coeffs dst)
2223{
2224  if ((SR_HDL(a) & SR_INT)||(a==NULL))
2225  {
2226    return a;
2227  }
2228  return _nlCopy_NoImm(a);
2229}
2230
2231nMapFunc nlSetMap(const coeffs src, const coeffs dst)
2232{
2233  if (src->rep==n_rep_gap_rat)  /*Q, coeffs_BIGINT */
2234  {
2235    return ndCopyMap;
2236  }
2237  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
2238  {
2239    return nlMapP;
2240  }
2241  if ((src->rep==n_rep_float) && nCoeff_is_R(src))
2242  {
2243    return nlMapR;
2244  }
2245  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
2246  {
2247    return nlMapLongR; /* long R -> Q */
2248  }
2249#ifdef HAVE_RINGS
2250  if (src->rep==n_rep_gmp) // nCoeff_is_Ring_Z(src) || nCoeff_is_Ring_PtoM(src) || nCoeff_is_Ring_ModN(src))
2251  {
2252    return nlMapGMP;
2253  }
2254  if (src->rep==n_rep_gap_gmp)
2255  {
2256    return nlMapZ;
2257  }
2258  if ((src->rep==n_rep_int) && nCoeff_is_Ring_2toM(src))
2259  {
2260    return nlMapMachineInt;
2261  }
2262#endif
2263  return NULL;
2264}
2265/*2
2266* z := i
2267*/
2268number nlRInit (long i)
2269{
2270  number z=ALLOC_RNUMBER();
2271#if defined(LDEBUG)
2272  z->debug=123456;
2273#endif
2274  mpz_init_set_si(z->z,i);
2275  z->s = 3;
2276  return z;
2277}
2278
2279/*2
2280* z := i/j
2281*/
2282number nlInit2 (int i, int j, const coeffs r)
2283{
2284  number z=ALLOC_RNUMBER();
2285#if defined(LDEBUG)
2286  z->debug=123456;
2287#endif
2288  mpz_init_set_si(z->z,(long)i);
2289  mpz_init_set_si(z->n,(long)j);
2290  z->s = 0;
2291  nlNormalize(z,r);
2292  return z;
2293}
2294
2295number nlInit2gmp (mpz_t i, mpz_t j, const coeffs r)
2296{
2297  number z=ALLOC_RNUMBER();
2298#if defined(LDEBUG)
2299  z->debug=123456;
2300#endif
2301  mpz_init_set(z->z,i);
2302  mpz_init_set(z->n,j);
2303  z->s = 0;
2304  nlNormalize(z,r);
2305  return z;
2306}
2307
2308#else // DO_LINLINE
2309
2310// declare immedate routines
2311number nlRInit (long i);
2312BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b);
2313number  _nlCopy_NoImm(number a);
2314number  _nlNeg_NoImm(number a);
2315number  _nlAdd_aNoImm_OR_bNoImm(number a, number b);
2316void    _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b);
2317number  _nlSub_aNoImm_OR_bNoImm(number a, number b);
2318number  _nlMult_aNoImm_OR_bNoImm(number a, number b);
2319number  _nlMult_aImm_bImm_rNoImm(number a, number b);
2320
2321#endif
2322
2323/***************************************************************
2324 *
2325 * Routines which might be inlined by p_Numbers.h
2326 *
2327 *******************************************************************/
2328#if defined(DO_LINLINE) || !defined(P_NUMBERS_H)
2329
2330// routines which are always inlined/static
2331
2332/*2
2333* a = b ?
2334*/
2335LINLINE BOOLEAN nlEqual (number a, number b, const coeffs r)
2336{
2337  nlTest(a, r);
2338  nlTest(b, r);
2339// short - short
2340  if (SR_HDL(a) & SR_HDL(b) & SR_INT) return a==b;
2341  return _nlEqual_aNoImm_OR_bNoImm(a, b);
2342}
2343
2344LINLINE number nlInit (long i, const coeffs r)
2345{
2346  number n;
2347  #if MAX_NUM_SIZE == 60
2348  if (((i << 3) >> 3) == i) n=INT_TO_SR(i);
2349  else                      n=nlRInit(i);
2350  #else
2351  LONG ii=(LONG)i;
2352  if ( (((long)ii==i) && ((ii << 3) >> 3) == ii )) n=INT_TO_SR(ii);
2353  else                                             n=nlRInit(i);
2354  #endif
2355  nlTest(n, r);
2356  return n;
2357}
2358
2359/*2
2360* a == 1 ?
2361*/
2362LINLINE BOOLEAN nlIsOne (number a, const coeffs r)
2363{
2364#ifdef LDEBUG
2365  if (a==NULL) return FALSE;
2366  nlTest(a, r);
2367#endif
2368  return (a==INT_TO_SR(1));
2369}
2370
2371LINLINE BOOLEAN nlIsZero (number a, const coeffs)
2372{
2373  #if 0
2374  if (a==INT_TO_SR(0)) return TRUE;
2375  if ((SR_HDL(a) & SR_INT)||(a==NULL)) return FALSE;
2376  if (mpz_cmp_si(a->z,(long)0)==0)
2377  {
2378    printf("gmp-0 in nlIsZero\n");
2379    dErrorBreak();
2380    return TRUE;
2381  }
2382  return FALSE;
2383  #else
2384  return (a==INT_TO_SR(0));
2385  #endif
2386}
2387
2388/*2
2389* copy a to b
2390*/
2391LINLINE number nlCopy(number a, const coeffs)
2392{
2393  if ((SR_HDL(a) & SR_INT)||(a==NULL))
2394  {
2395    return a;
2396  }
2397  return _nlCopy_NoImm(a);
2398}
2399
2400
2401/*2
2402* delete a
2403*/
2404LINLINE void nlDelete (number * a, const coeffs r)
2405{
2406  if (*a!=NULL)
2407  {
2408    nlTest(*a, r);
2409    if ((SR_HDL(*a) & SR_INT)==0)
2410    {
2411      _nlDelete_NoImm(a);
2412    }
2413    *a=NULL;
2414  }
2415}
2416
2417/*2
2418* za:= - za
2419*/
2420LINLINE number nlNeg (number a, const coeffs R)
2421{
2422  nlTest(a, R);
2423  if(SR_HDL(a) &SR_INT)
2424  {
2425    LONG r=SR_TO_INT(a);
2426    if (r==(-(POW_2_28))) a=nlRInit(POW_2_28);
2427    else               a=INT_TO_SR(-r);
2428    return a;
2429  }
2430  a = _nlNeg_NoImm(a);
2431  nlTest(a, R);
2432  return a;
2433
2434}
2435
2436/*2
2437* u:= a + b
2438*/
2439LINLINE number nlAdd (number a, number b, const coeffs R)
2440{
2441  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2442  {
2443    LONG r=SR_HDL(a)+SR_HDL(b)-1L;
2444    if ( ((r << 1) >> 1) == r )
2445      return (number)(long)r;
2446    else
2447      return nlRInit(SR_TO_INT(r));
2448  }
2449  number u =  _nlAdd_aNoImm_OR_bNoImm(a, b);
2450  nlTest(u, R);
2451  return u;
2452}
2453
2454number nlShort1(number a);
2455number nlShort3_noinline(number x);
2456
2457LINLINE void nlInpAdd(number &a, number b, const coeffs r)
2458{
2459  // a=a+b
2460  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2461  {
2462    LONG r=SR_HDL(a)+SR_HDL(b)-1L;
2463    if ( ((r << 1) >> 1) == r )
2464      a=(number)(long)r;
2465    else
2466      a=nlRInit(SR_TO_INT(r));
2467  }
2468  else
2469  {
2470    _nlInpAdd_aNoImm_OR_bNoImm(a,b);
2471    nlTest(a,r);
2472  }
2473}
2474
2475LINLINE number nlMult (number a, number b, const coeffs R)
2476{
2477  nlTest(a, R);
2478  nlTest(b, R);
2479  if (a==INT_TO_SR(0)) return INT_TO_SR(0);
2480  if (b==INT_TO_SR(0)) return INT_TO_SR(0);
2481  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2482  {
2483    LONG r=(LONG)((unsigned LONG)(SR_HDL(a)-1L))*((unsigned LONG)(SR_HDL(b)>>1));
2484    if ((r/(SR_HDL(b)>>1))==(SR_HDL(a)-1L))
2485    {
2486      number u=((number) ((r>>1)+SR_INT));
2487      if (((((LONG)SR_HDL(u))<<1)>>1)==SR_HDL(u)) return (u);
2488      return nlRInit(SR_HDL(u)>>2);
2489    }
2490    number u = _nlMult_aImm_bImm_rNoImm(a, b);
2491    nlTest(u, R);
2492    return u;
2493
2494  }
2495  number u = _nlMult_aNoImm_OR_bNoImm(a, b);
2496  nlTest(u, R);
2497  return u;
2498
2499}
2500
2501
2502/*2
2503* u:= a - b
2504*/
2505LINLINE number nlSub (number a, number b, const coeffs r)
2506{
2507  if (SR_HDL(a) & SR_HDL(b) & SR_INT)
2508  {
2509    LONG r=SR_HDL(a)-SR_HDL(b)+1;
2510    if ( ((r << 1) >> 1) == r )
2511    {
2512      return (number)(long)r;
2513    }
2514    else
2515      return nlRInit(SR_TO_INT(r));
2516  }
2517  number u = _nlSub_aNoImm_OR_bNoImm(a, b);
2518  nlTest(u, r);
2519  return u;
2520
2521}
2522
2523LINLINE void nlInpMult(number &a, number b, const coeffs r)
2524{
2525  number aa=a;
2526  if (((SR_HDL(b)|SR_HDL(aa))&SR_INT))
2527  {
2528    number n=nlMult(aa,b,r);
2529    nlDelete(&a,r);
2530    a=n;
2531  }
2532  else
2533  {
2534    mpz_mul(aa->z,a->z,b->z);
2535    if (aa->s==3)
2536    {
2537      if(b->s!=3)
2538      {
2539        mpz_init_set(a->n,b->n);
2540        a->s=0;
2541      }
2542    }
2543    else
2544    {
2545      if(b->s!=3)
2546      {
2547        mpz_mul(a->n,a->n,b->n);
2548      }
2549      a->s=0;
2550    }
2551  }
2552}
2553#endif // DO_LINLINE
2554
2555#ifndef P_NUMBERS_H
2556
2557static void nlMPZ(mpz_t m, number &n, const coeffs r)
2558{
2559  nlTest(n, r);
2560  nlNormalize(n, r);
2561  if (SR_HDL(n) & SR_INT) mpz_init_set_si(m, SR_TO_INT(n));     /* n fits in an int */
2562  else             mpz_init_set(m, (mpz_ptr)n->z);
2563}
2564
2565
2566static number nlInitMPZ(mpz_t m, const coeffs)
2567{
2568  number z = ALLOC_RNUMBER();
2569  mpz_init_set(z->z, m);
2570  mpz_init_set_ui(z->n, 1);
2571  z->s = 3;
2572  return z;
2573}
2574
2575
2576void nlInpGcd(number &a, number b, const coeffs r)
2577{
2578  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2579  {
2580    number n=nlGcd(a,b,r);
2581    nlDelete(&a,r);
2582    a=n;
2583  }
2584  else
2585  {
2586    mpz_gcd(a->z,a->z,b->z);
2587    a=nlShort3_noinline(a);
2588  }
2589}
2590
2591void nlInpIntDiv(number &a, number b, const coeffs r)
2592{
2593  if ((SR_HDL(b)|SR_HDL(a))&SR_INT)
2594  {
2595    number n=nlIntDiv(a,b, r);
2596    nlDelete(&a,r);
2597    a=n;
2598  }
2599  else
2600  {
2601    if (mpz_isNeg(a->z))
2602    {
2603      if (mpz_isNeg(b->z))
2604      {
2605        mpz_add(a->z,a->z,b->z);
2606      }
2607      else
2608      {
2609        mpz_sub(a->z,a->z,b->z);
2610      }
2611      mpz_add_ui(a->z,a->z,1);
2612    }
2613    else
2614    {
2615      if (mpz_isNeg(b->z))
2616      {
2617        mpz_sub(a->z,a->z,b->z);
2618      }
2619      else
2620      {
2621        mpz_add(a->z,a->z,b->z);
2622      }
2623      mpz_sub_ui(a->z,a->z,1);
2624    }
2625    MPZ_DIV(a->z,a->z,b->z);
2626    a=nlShort3_noinline(a);
2627  }
2628}
2629
2630number nlFarey(number nN, number nP, const coeffs r)
2631{
2632  mpz_t tmp; mpz_init(tmp);
2633  mpz_t A,B,C,D,E,N,P;
2634  if (SR_HDL(nN) & SR_INT) mpz_init_set_si(N,SR_TO_INT(nN));
2635  else                     mpz_init_set(N,nN->z);
2636  if (SR_HDL(nP) & SR_INT) mpz_init_set_si(P,SR_TO_INT(nP));
2637  else                     mpz_init_set(P,nP->z);
2638  assume(!mpz_isNeg(P));
2639  if (mpz_isNeg(N))  mpz_add(N,N,P);
2640  mpz_init_set_si(A,(long)0);
2641  mpz_init_set_ui(B,(unsigned long)1);
2642  mpz_init_set_si(C,(long)0);
2643  mpz_init(D);
2644  mpz_init_set(E,P);
2645  number z=INT_TO_SR(0);
2646  while(mpz_cmp_si(N,(long)0)!=0)
2647  {
2648    mpz_mul(tmp,N,N);
2649    mpz_add(tmp,tmp,tmp);
2650    if (mpz_cmp(tmp,P)<0)
2651    {
2652       if (mpz_isNeg(B))
2653       {
2654         mpz_neg(B,B);
2655         mpz_neg(N,N);
2656       }
2657       // check for gcd(N,B)==1
2658       mpz_gcd(tmp,N,B);
2659       if (mpz_cmp_ui(tmp,1)==0)
2660       {
2661         // return N/B
2662         z=ALLOC_RNUMBER();
2663         #ifdef LDEBUG
2664         z->debug=123456;
2665         #endif
2666         mpz_init_set(z->z,N);
2667         mpz_init_set(z->n,B);
2668         z->s = 0;
2669         nlNormalize(z,r);
2670       }
2671       else
2672       {
2673         // return nN (the input) instead of "fail"
2674         z=nlCopy(nN,r);
2675       }
2676       break;
2677    }
2678    //mpz_mod(D,E,N);
2679    //mpz_div(tmp,E,N);
2680    mpz_divmod(tmp,D,E,N);
2681    mpz_mul(tmp,tmp,B);
2682    mpz_sub(C,A,tmp);
2683    mpz_set(E,N);
2684    mpz_set(N,D);
2685    mpz_set(A,B);
2686    mpz_set(B,C);
2687  }
2688  mpz_clear(tmp);
2689  mpz_clear(A);
2690  mpz_clear(B);
2691  mpz_clear(C);
2692  mpz_clear(D);
2693  mpz_clear(E);
2694  mpz_clear(N);
2695  mpz_clear(P);
2696  return z;
2697}
2698
2699number nlExtGcd(number a, number b, number *s, number *t, const coeffs)
2700{
2701  mpz_t aa,bb;
2702  *s=ALLOC_RNUMBER();
2703  mpz_init((*s)->z); (*s)->s=3;
2704  (*t)=ALLOC_RNUMBER();
2705  mpz_init((*t)->z); (*t)->s=3;
2706  number g=ALLOC_RNUMBER();
2707  mpz_init(g->z); g->s=3;
2708  if (SR_HDL(a) & SR_INT)
2709  {
2710    mpz_init_set_si(aa,SR_TO_INT(a));
2711  }
2712  else
2713  {
2714    mpz_init_set(aa,a->z);
2715  }
2716  if (SR_HDL(b) & SR_INT)
2717  {
2718    mpz_init_set_si(bb,SR_TO_INT(b));
2719  }
2720  else
2721  {
2722    mpz_init_set(bb,b->z);
2723  }
2724  mpz_gcdext(g->z,(*s)->z,(*t)->z,aa,bb);
2725  mpz_clear(aa);
2726  mpz_clear(bb);
2727  (*s)=nlShort3((*s));
2728  (*t)=nlShort3((*t));
2729  g=nlShort3(g);
2730  return g;
2731}
2732
2733void    nlCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
2734{
2735  if (r->is_field)
2736  PrintS("//   characteristic : 0\n");
2737  else
2738  PrintS("//   coeff. ring is : Integers\n");
2739}
2740
2741number   nlChineseRemainderSym(number *x, number *q,int rl, BOOLEAN sym, const coeffs CF)
2742// elemenst in the array are x[0..(rl-1)], q[0..(rl-1)]
2743{
2744  setCharacteristic( 0 ); // only in char 0
2745  Off(SW_RATIONAL);
2746  CFArray X(rl), Q(rl);
2747  int i;
2748  for(i=rl-1;i>=0;i--)
2749  {
2750    X[i]=CF->convSingNFactoryN(x[i],FALSE,CF); // may be larger MAX_INT
2751    Q[i]=CF->convSingNFactoryN(q[i],FALSE,CF); // may be larger MAX_INT
2752  }
2753  CanonicalForm xnew,qnew;
2754  chineseRemainder(X,Q,xnew,qnew);
2755  number n=CF->convFactoryNSingN(xnew,CF);
2756  if (sym)
2757  {
2758    number p=CF->convFactoryNSingN(qnew,CF);
2759    number p2=nlIntDiv(p,nlInit(2, CF),CF);
2760    if (nlGreater(n,p2,CF))
2761    {
2762       number n2=nlSub(n,p,CF);
2763       nlDelete(&n,CF);
2764       n=n2;
2765    }
2766    nlDelete(&p2,CF);
2767    nlDelete(&p,CF);
2768  }
2769  nlNormalize(n,CF);
2770  return n;
2771}
2772number   nlChineseRemainder(number *x, number *q,int rl, const coeffs C)
2773{
2774  return nlChineseRemainderSym(x,q,rl,TRUE,C);
2775}
2776
2777static void nlClearContent(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
2778{
2779  assume(cf != NULL);
2780
2781  numberCollectionEnumerator.Reset();
2782
2783  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
2784  {
2785    c = nlInit(1, cf);
2786    return;
2787  }
2788
2789  // all coeffs are given by integers!!!
2790
2791  // part 1, find a small candidate for gcd
2792  number cand1,cand;
2793  int s1,s;
2794  s=2147483647; // max. int
2795
2796  const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf);
2797
2798  int normalcount = 0;
2799  do
2800  {
2801    number& n = numberCollectionEnumerator.Current();
2802    nlNormalize(n, cf); ++normalcount;
2803    cand1 = n;
2804
2805    if (SR_HDL(cand1)&SR_INT) { cand=cand1; break; }
2806    assume(cand1->s==3); // all coeffs should be integers // ==0?!! after printing
2807    s1=mpz_size1(cand1->z);
2808    if (s>s1)
2809    {
2810      cand=cand1;
2811      s=s1;
2812    }
2813  } while (numberCollectionEnumerator.MoveNext() );
2814
2815//  assume( nlGreaterZero(cand,cf) ); // cand may be a negative integer!
2816
2817  cand=nlCopy(cand,cf);
2818  // part 2: compute gcd(cand,all coeffs)
2819
2820  numberCollectionEnumerator.Reset();
2821
2822  while (numberCollectionEnumerator.MoveNext() )
2823  {
2824    number& n = numberCollectionEnumerator.Current();
2825
2826    if( (--normalcount) <= 0)
2827      nlNormalize(n, cf);
2828
2829    nlInpGcd(cand, n, cf);
2830    assume( nlGreaterZero(cand,cf) );
2831
2832    if(nlIsOne(cand,cf))
2833    {
2834      c = cand;
2835
2836      if(!lc_is_pos)
2837      {
2838        // make the leading coeff positive
2839        c = nlNeg(c, cf);
2840        numberCollectionEnumerator.Reset();
2841
2842        while (numberCollectionEnumerator.MoveNext() )
2843        {
2844          number& nn = numberCollectionEnumerator.Current();
2845          nn = nlNeg(nn, cf);
2846        }
2847      }
2848      return;
2849    }
2850  }
2851
2852  // part3: all coeffs = all coeffs / cand
2853  if (!lc_is_pos)
2854    cand = nlNeg(cand,cf);
2855
2856  c = cand;
2857  numberCollectionEnumerator.Reset();
2858
2859  while (numberCollectionEnumerator.MoveNext() )
2860  {
2861    number& n = numberCollectionEnumerator.Current();
2862    number t=nlIntDiv(n, cand, cf); // simple integer exact division, no ratios to remain
2863    nlDelete(&n, cf);
2864    n = t;
2865  }
2866}
2867
2868static void nlClearDenominators(ICoeffsEnumerator& numberCollectionEnumerator, number& c, const coeffs cf)
2869{
2870  assume(cf != NULL);
2871
2872  numberCollectionEnumerator.Reset();
2873
2874  if( !numberCollectionEnumerator.MoveNext() ) // empty zero polynomial?
2875  {
2876    c = nlInit(1, cf);
2877//    assume( n_GreaterZero(c, cf) );
2878    return;
2879  }
2880
2881  // all coeffs are given by integers after returning from this routine
2882
2883  // part 1, collect product of all denominators /gcds
2884  number cand;
2885  cand=ALLOC_RNUMBER();
2886#if defined(LDEBUG)
2887  cand->debug=123456;
2888#endif
2889  cand->s=3;
2890
2891  int s=0;
2892
2893  const BOOLEAN lc_is_pos=nlGreaterZero(numberCollectionEnumerator.Current(),cf);
2894
2895  do
2896  {
2897    number& cand1 = numberCollectionEnumerator.Current();
2898
2899    if (!(SR_HDL(cand1)&SR_INT))
2900    {
2901      nlNormalize(cand1, cf);
2902      if ((!(SR_HDL(cand1)&SR_INT)) // not a short int
2903      && (cand1->s==1))             // and is a normalised rational
2904      {
2905        if (s==0) // first denom, we meet
2906        {
2907          mpz_init_set(cand->z, cand1->n); // cand->z = cand1->n
2908          s=1;
2909        }
2910        else // we have already something
2911        {
2912          mpz_lcm(cand->z, cand->z, cand1->n);
2913        }
2914      }
2915    }
2916  }
2917  while (numberCollectionEnumerator.MoveNext() );
2918
2919
2920  if (s==0) // nothing to do, all coeffs are already integers
2921  {
2922//    mpz_clear(tmp);
2923    FREE_RNUMBER(cand);
2924    if (lc_is_pos)
2925      c=nlInit(1,cf);
2926    else
2927    {
2928      // make the leading coeff positive
2929      c=nlInit(-1,cf);
2930
2931      // TODO: incorporate the following into the loop below?
2932      numberCollectionEnumerator.Reset();
2933      while (numberCollectionEnumerator.MoveNext() )
2934      {
2935        number& n = numberCollectionEnumerator.Current();
2936        n = nlNeg(n, cf);
2937      }
2938    }
2939//    assume( n_GreaterZero(c, cf) );
2940    return;
2941  }
2942
2943  cand = nlShort3(cand);
2944
2945  // part2: all coeffs = all coeffs * cand
2946  // make the lead coeff positive
2947  numberCollectionEnumerator.Reset();
2948
2949  if (!lc_is_pos)
2950    cand = nlNeg(cand, cf);
2951
2952  c = cand;
2953
2954  while (numberCollectionEnumerator.MoveNext() )
2955  {
2956    number &n = numberCollectionEnumerator.Current();
2957    nlInpMult(n, cand, cf);
2958  }
2959
2960}
2961
2962char * nlCoeffName(const coeffs r)
2963{
2964  if (r->cfDiv==nlDiv) return (char*)"QQ";
2965  else                 return (char*)"ZZ";
2966}
2967
2968static char* nlCoeffString(const coeffs r)
2969{
2970  //return omStrDup(nlCoeffName(r));
2971  if (r->cfDiv==nlDiv) return omStrDup("0");
2972  else                 return omStrDup("integer");
2973}
2974
2975#define SSI_BASE 16
2976
2977static void nlWriteFd(number n,FILE* f, const coeffs)
2978{
2979  if(SR_HDL(n) & SR_INT)
2980  {
2981    #if SIZEOF_LONG == 4
2982    fprintf(f,"4 %ld ",SR_TO_INT(n));
2983    #else
2984    long nn=SR_TO_INT(n);
2985    if ((nn<POW_2_28_32)&&(nn>= -POW_2_28_32))
2986    {
2987      int nnn=(int)nn;
2988      fprintf(f,"4 %d ",nnn);
2989    }
2990    else
2991    {
2992      mpz_t tmp;
2993      mpz_init_set_si(tmp,nn);
2994      fputs("8 ",f);
2995      mpz_out_str (f,SSI_BASE, tmp);
2996      fputc(' ',f);
2997      mpz_clear(tmp);
2998    }
2999    #endif
3000  }
3001  else if (n->s<2)
3002  {
3003    //gmp_fprintf(f,"%d %Zd %Zd ",n->s,n->z,n->n);
3004    fprintf(f,"%d ",n->s+5);
3005    mpz_out_str (f,SSI_BASE, n->z);
3006    fputc(' ',f);
3007    mpz_out_str (f,SSI_BASE, n->n);
3008    fputc(' ',f);
3009
3010    //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: s=%d gmp/gmp \"%Zd %Zd\" ",n->s,n->z,n->n);
3011  }
3012  else /*n->s==3*/
3013  {
3014    //gmp_fprintf(d->f_write,"3 %Zd ",n->z);
3015    fputs("8 ",f);
3016    mpz_out_str (f,SSI_BASE, n->z);
3017    fputc(' ',f);
3018
3019    //if (d->f_debug!=NULL) gmp_fprintf(d->f_debug,"number: gmp \"%Zd\" ",n->z);
3020  }
3021}
3022
3023static number nlReadFd(s_buff f, const coeffs)
3024{
3025  int sub_type=-1;
3026  sub_type=s_readint(f);
3027  switch(sub_type)
3028  {
3029     case 0:
3030     case 1:
3031       {// read mpz_t, mpz_t
3032         number n=nlRInit(0);
3033         mpz_init(n->n);
3034         s_readmpz(f,n->z);
3035         s_readmpz(f,n->n);
3036         n->s=sub_type;
3037         return n;
3038       }
3039
3040     case 3:
3041       {// read mpz_t
3042         number n=nlRInit(0);
3043         s_readmpz(f,n->z);
3044         n->s=3; /*sub_type*/
3045         #if SIZEOF_LONG == 8
3046         n=nlShort3(n);
3047         #endif
3048         return n;
3049       }
3050     case 4:
3051       {
3052         LONG dd=s_readlong(f);
3053         //#if SIZEOF_LONG == 8
3054         return INT_TO_SR(dd);
3055         //#else
3056         //return nlInit(dd,NULL);
3057         //#endif
3058       }
3059     case 5:
3060     case 6:
3061       {// read raw mpz_t, mpz_t
3062         number n=nlRInit(0);
3063         mpz_init(n->n);
3064         s_readmpz_base (f,n->z, SSI_BASE);
3065         s_readmpz_base (f,n->n, SSI_BASE);
3066         n->s=sub_type-5;
3067         return n;
3068       }
3069     case 8:
3070       {// read raw mpz_t
3071         number n=nlRInit(0);
3072         s_readmpz_base (f,n->z, SSI_BASE);
3073         n->s=sub_type=3; /*subtype-5*/
3074         #if SIZEOF_LONG == 8
3075         n=nlShort3(n);
3076         #endif
3077         return n;
3078       }
3079
3080     default: Werror("error in reading number: invalid subtype %d",sub_type);
3081              return NULL;
3082  }
3083  return NULL;
3084}
3085BOOLEAN nlCoeffIsEqual(const coeffs r, n_coeffType n, void *p)
3086{
3087  /* test, if r is an instance of nInitCoeffs(n,parameter) */
3088  /* if parameter is not needed */
3089  if (n==r->type)
3090  {
3091    if ((p==NULL)&&(r->cfDiv==nlDiv)) return TRUE;
3092    if ((p!=NULL)&&(r->cfDiv!=nlDiv)) return TRUE;
3093  }
3094  return FALSE;
3095}
3096
3097static number nlLcm(number a,number b,const coeffs r)
3098{
3099  number g=nlGcd(a,b,r);
3100  number n1=nlMult(a,b,r);
3101  number n2=nlDiv(n1,g,r);
3102  nlDelete(&g,r);
3103  nlDelete(&n1,r);
3104  return n2;
3105}
3106
3107static number nlRandom(siRandProc p, number v2, number, const coeffs cf)
3108{
3109  number a=nlInit(p(),cf);
3110  if (v2!=NULL)
3111  {
3112    number b=nlInit(p(),cf);
3113    number c=nlDiv(a,b,cf);
3114    nlDelete(&b,cf);
3115    nlDelete(&a,cf);
3116    a=c;
3117  }
3118  return a;
3119}
3120
3121BOOLEAN nlInitChar(coeffs r, void*p)
3122{
3123  r->is_domain=TRUE;
3124  r->rep=n_rep_gap_rat;
3125
3126  //const int ch = (int)(long)(p);
3127
3128  r->nCoeffIsEqual=nlCoeffIsEqual;
3129  //r->cfKillChar = ndKillChar; /* dummy */
3130  r->cfCoeffString=nlCoeffString;
3131  r->cfCoeffName=nlCoeffName;
3132
3133  r->cfInitMPZ = nlInitMPZ;
3134  r->cfMPZ  = nlMPZ;
3135
3136  r->cfMult  = nlMult;
3137  r->cfSub   = nlSub;
3138  r->cfAdd   = nlAdd;
3139  if (p==NULL) /* Q */
3140  {
3141    r->is_field=TRUE;
3142    r->cfDiv   = nlDiv;
3143    //r->cfGcd  = ndGcd_dummy;
3144    r->cfSubringGcd  = nlGcd;
3145  }
3146  else /* Z: coeffs_BIGINT */
3147  {
3148    r->is_field=FALSE;
3149    r->cfDiv   = nlIntDiv;
3150    r->cfIntMod= nlIntMod;
3151    r->cfGcd  = nlGcd;
3152    r->cfDivBy=nlDivBy;
3153    r->cfDivComp = nlDivComp;
3154    r->cfIsUnit = nlIsUnit;
3155    r->cfGetUnit = nlGetUnit;
3156    r->cfQuot1 = nlQuot1;
3157    r->cfLcm = nlLcm;
3158  }
3159  r->cfExactDiv= nlExactDiv;
3160  r->cfInit = nlInit;
3161  r->cfSize  = nlSize;
3162  r->cfInt  = nlInt;
3163
3164  r->cfChineseRemainder=nlChineseRemainderSym;
3165  r->cfFarey=nlFarey;
3166  r->cfInpNeg   = nlNeg;
3167  r->cfInvers= nlInvers;
3168  r->cfCopy  = nlCopy;
3169  r->cfRePart = nlCopy;
3170  //r->cfImPart = ndReturn0;
3171  r->cfWriteLong = nlWrite;
3172  r->cfRead = nlRead;
3173  r->cfNormalize=nlNormalize;
3174  r->cfGreater = nlGreater;
3175  r->cfEqual = nlEqual;
3176  r->cfIsZero = nlIsZero;
3177  r->cfIsOne = nlIsOne;
3178  r->cfIsMOne = nlIsMOne;
3179  r->cfGreaterZero = nlGreaterZero;
3180  r->cfPower = nlPower;
3181  r->cfGetDenom = nlGetDenom;
3182  r->cfGetNumerator = nlGetNumerator;
3183  r->cfExtGcd = nlExtGcd; // only for ring stuff and Z
3184  r->cfNormalizeHelper  = nlNormalizeHelper;
3185  r->cfDelete= nlDelete;
3186  r->cfSetMap = nlSetMap;
3187  //r->cfName = ndName;
3188  r->cfInpMult=nlInpMult;
3189  r->cfInpAdd=nlInpAdd;
3190  r->cfCoeffWrite=nlCoeffWrite;
3191
3192  r->cfClearContent = nlClearContent;
3193  r->cfClearDenominators = nlClearDenominators;
3194
3195#ifdef LDEBUG
3196  // debug stuff
3197  r->cfDBTest=nlDBTest;
3198#endif
3199  r->convSingNFactoryN=nlConvSingNFactoryN;
3200  r->convFactoryNSingN=nlConvFactoryNSingN;
3201
3202  r->cfRandom=nlRandom;
3203
3204  // io via ssi
3205  r->cfWriteFd=nlWriteFd;
3206  r->cfReadFd=nlReadFd;
3207
3208  // the variables: general stuff (required)
3209  r->nNULL = INT_TO_SR(0);
3210  //r->type = n_Q;
3211  r->ch = 0;
3212  r->has_simple_Alloc=FALSE;
3213  r->has_simple_Inverse=FALSE;
3214
3215  // variables for this type of coeffs:
3216  // (none)
3217  return FALSE;
3218}
3219#if 0
3220number nlMod(number a, number b)
3221{
3222  if (((SR_HDL(b)&SR_HDL(a))&SR_INT)
3223  {
3224    int bi=SR_TO_INT(b);
3225    int ai=SR_TO_INT(a);
3226    int bb=ABS(bi);
3227    int c=ai%bb;
3228    if (c<0)  c+=bb;
3229    return (INT_TO_SR(c));
3230  }
3231  number al;
3232  number bl;
3233  if (SR_HDL(a))&SR_INT)
3234    al=nlRInit(SR_TO_INT(a));
3235  else
3236    al=nlCopy(a);
3237  if (SR_HDL(b))&SR_INT)
3238    bl=nlRInit(SR_TO_INT(b));
3239  else
3240    bl=nlCopy(b);
3241  number r=nlRInit(0);
3242  mpz_mod(r->z,al->z,bl->z);
3243  nlDelete(&al);
3244  nlDelete(&bl);
3245  if (mpz_size1(&r->z)<=MP_SMALL)
3246  {
3247    LONG ui=(int)mpz_get_si(&r->z);
3248    if ((((ui<<3)>>3)==ui)
3249    && (mpz_cmp_si(x->z,(long)ui)==0))
3250    {
3251      mpz_clear(&r->z);
3252      FREE_RNUMBER(r); //  omFreeBin((void *)r, rnumber_bin);
3253      r=INT_TO_SR(ui);
3254    }
3255  }
3256  return r;
3257}
3258#endif
3259#endif // not P_NUMBERS_H
3260#endif // LONGRAT_CC
Note: See TracBrowser for help on using the repository browser.