longrat.cc
Go to the documentation of this file.
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 
29 LINLINE BOOLEAN nlEqual(number a, number b, const coeffs r);
30 LINLINE number nlInit(long i, const coeffs r);
31 LINLINE BOOLEAN nlIsOne(number a, const coeffs r);
32 LINLINE BOOLEAN nlIsZero(number za, const coeffs r);
33 LINLINE number nlCopy(number a, const coeffs r);
34 LINLINE number nl_Copy(number a, const coeffs r);
35 LINLINE void nlDelete(number *a, const coeffs r);
36 LINLINE number nlNeg(number za, const coeffs r);
37 LINLINE number nlAdd(number la, number li, const coeffs r);
38 LINLINE number nlSub(number la, number li, const coeffs r);
39 LINLINE number nlMult(number a, number b, const coeffs r);
40 LINLINE void nlInpAdd(number &a, number b, const coeffs r);
41 LINLINE void nlInpMult(number &a, number b, const coeffs r);
42 
43 number 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 
49 void nlNormalize(number &x, const coeffs r);
50 
51 number nlGcd(number a, number b, const coeffs r);
52 number nlExtGcd(number a, number b, number *s, number *t, const coeffs);
53 number nlNormalizeHelper(number a, number b, const coeffs r); /*special routine !*/
54 BOOLEAN nlGreater(number a, number b, const coeffs r);
55 BOOLEAN nlIsMOne(number a, const coeffs r);
56 long nlInt(number &n, const coeffs r);
57 number nlBigInt(number &n);
58 
59 #ifdef HAVE_RINGS
60 number nlMapGMP(number from, const coeffs src, const coeffs dst);
61 #endif
62 
63 BOOLEAN nlGreaterZero(number za, const coeffs r);
64 number nlInvers(number a, const coeffs r);
65 number nlDiv(number a, number b, const coeffs r);
66 number nlExactDiv(number a, number b, const coeffs r);
67 number nlIntDiv(number a, number b, const coeffs r);
68 number nlIntMod(number a, number b, const coeffs r);
69 void nlPower(number x, int exp, number *lu, const coeffs r);
70 const char * nlRead (const char *s, number *a, const coeffs r);
71 void nlWrite(number &a, const coeffs r);
72 
73 number nlGetDenom(number &n, const coeffs r);
74 number nlGetNumerator(number &n, const coeffs r);
75 void nlCoeffWrite(const coeffs r, BOOLEAN details);
76 number nlChineseRemainder(number *x, number *q,int rl, const coeffs C);
77 number nlFarey(number nN, number nP, const coeffs CF);
78 
79 #ifdef LDEBUG
80 BOOLEAN nlDBTest(number a, const char *f, const int l);
81 #endif
82 
83 nMapFunc nlSetMap(const coeffs src, const coeffs dst);
84 
85 // in-place operations
86 void nlInpIntDiv(number &a, number b, const coeffs r);
87 
88 #ifdef LDEBUG
89 #define nlTest(a, r) nlDBTest(a,__FILE__,__LINE__, r)
90 BOOLEAN 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 
110 static 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 
163 void _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 
172 number 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)
179 void 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 
191 static 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 
200 static number nlMapLongR(number from, const coeffs src, const coeffs dst);
201 static 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 */
208 number 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 
221 number 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 */
233 number 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
248 BOOLEAN 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 
340 static CanonicalForm nlConvSingNFactoryN( number n, const BOOLEAN setChar, const coeffs /*r*/ )
341 {
342  if (setChar) setCharacteristic( 0 );
343 
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 
376 number nlRInit (long i);
377 
378 static 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 
403 static 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 
433 static 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 
575 int 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 */
604 long 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 */
636 number 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 */
654 number 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 */
733 number 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 */
784 number 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 */
850 number 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 
909 BOOLEAN 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 
923 int 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 
934 number 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 
942 coeffs 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 
956 BOOLEAN 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 */
965 number 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 */
1075 void 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 */
1128 BOOLEAN 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 */
1138 BOOLEAN 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 */
1153 BOOLEAN 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 */
1165 number 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 
1243 number 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 */
1264 void 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 */
1308 number 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)
1355 number 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 */
1397 void 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 */
1418 number 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 */
1447 number 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  *******************************************************************/
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
1525 number _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 
1546 void _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 
1564 number _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 
1576 number _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 
1742 void _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 
1881 number _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
2105 number _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
2118 number _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 */
2222 number 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 
2231 nMapFunc 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 */
2268 number 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 */
2282 number 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 
2295 number 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
2311 number nlRInit (long i);
2312 BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b);
2313 number _nlCopy_NoImm(number a);
2314 number _nlNeg_NoImm(number a);
2315 number _nlAdd_aNoImm_OR_bNoImm(number a, number b);
2316 void _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b);
2317 number _nlSub_aNoImm_OR_bNoImm(number a, number b);
2318 number _nlMult_aNoImm_OR_bNoImm(number a, number b);
2319 number _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 */
2335 LINLINE 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 
2344 LINLINE 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 */
2362 LINLINE 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 
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 */
2391 LINLINE 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 */
2404 LINLINE 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 */
2420 LINLINE 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 */
2439 LINLINE 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 
2454 number nlShort1(number a);
2455 number nlShort3_noinline(number x);
2456 
2457 LINLINE 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  {
2471  nlTest(a,r);
2472  }
2473 }
2474 
2475 LINLINE 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 */
2505 LINLINE 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 
2523 LINLINE 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 
2557 static 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 
2566 static 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 
2576 void 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 
2591 void 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 
2630 number 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 
2699 number 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 
2733 void 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 
2741 number 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 }
2772 number nlChineseRemainder(number *x, number *q,int rl, const coeffs C)
2773 {
2774  return nlChineseRemainderSym(x,q,rl,TRUE,C);
2775 }
2776 
2777 static 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 
2868 static 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 
2962 char * nlCoeffName(const coeffs r)
2963 {
2964  if (r->cfDiv==nlDiv) return (char*)"QQ";
2965  else return (char*)"ZZ";
2966 }
2967 
2968 static 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 
2977 static 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 
3023 static 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 }
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 
3097 static 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 
3107 static 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 
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
3220 number 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
mpz_ptr base
Definition: rmodulon.h:18
void gmp_numerator(const CanonicalForm &f, mpz_ptr result)
Definition: singext.cc:20
mpz_t z
Definition: longrat.h:48
const const intvec const intvec const ring _currRing const const intvec const intvec const ring _currRing int
Definition: gb_hack.h:53
number nlGetUnit(number n, const coeffs r)
Definition: longrat.cc:934
LINLINE number nlSub(number la, number li, const coeffs r)
Definition: longrat.cc:2505
static void nlClearDenominators(ICoeffsEnumerator &numberCollectionEnumerator, number &c, const coeffs cf)
Definition: longrat.cc:2868
#define MPZ_EXACTDIV(A, B, C)
Definition: longrat.cc:161
const CanonicalForm int s
Definition: facAbsFact.cc:55
const CanonicalForm int const CFList const Variable & y
Definition: facAbsFact.cc:57
void mpz_mul_si(mpz_ptr r, mpz_srcptr s, long int si)
Definition: longrat.cc:179
#define omCheckAddrSize(addr, size)
Definition: omAllocDecl.h:327
#define INT_TO_SR(INT)
Definition: longrat.h:66
const poly a
Definition: syzextra.cc:212
BOOLEAN nlCoeffIsEqual(const coeffs r, n_coeffType n, void *p)
Definition: longrat.cc:3085
#define Print
Definition: emacs.cc:83
only used if HAVE_RINGS is defined: ?
Definition: coeffs.h:42
static FORCE_INLINE BOOLEAN nCoeff_is_Zp(const coeffs r)
Definition: coeffs.h:816
char * nlCoeffName(const coeffs r)
Definition: longrat.cc:2962
void Off(int sw)
switches
CanonicalForm num(const CanonicalForm &f)
long npInt(number &n, const coeffs r)
Definition: modulop.cc:145
Definition: int_poly.h:36
static number nlConvFactoryNSingN(const CanonicalForm f, const coeffs r)
Definition: longrat.cc:378
BOOLEAN nlGreaterZero(number za, const coeffs r)
Definition: longrat.cc:1128
#define FALSE
Definition: auxiliary.h:140
static void nlMPZ(mpz_t m, number &n, const coeffs r)
Definition: longrat.cc:2557
mpf_t * _mpfp()
Definition: mpr_complex.h:134
return P p
Definition: myNF.cc:203
number _nlMult_aNoImm_OR_bNoImm(number a, number b)
Definition: longrat.cc:2118
f
Definition: cfModGcd.cc:4022
number nlShort1(number x)
Definition: longrat.cc:1243
number nlNormalizeHelper(number a, number b, const coeffs r)
Definition: longrat.cc:1308
number ndCopyMap(number a, const coeffs aRing, const coeffs r)
Definition: numbers.cc:228
static FORCE_INLINE BOOLEAN nCoeff_is_long_R(const coeffs r)
Definition: coeffs.h:887
LINLINE void nlInpAdd(number &a, number b, const coeffs r)
Definition: longrat.cc:2457
number nlGetDenom(number &n, const coeffs r)
Definition: longrat.cc:1418
int nlSize(number a, const coeffs)
Definition: longrat.cc:575
static FORCE_INLINE number n_Init(long i, const coeffs r)
a number representing i in the given coeff field/ring r
Definition: coeffs.h:537
static FORCE_INLINE BOOLEAN nCoeff_is_R(const coeffs r)
Definition: coeffs.h:829
#define omCheckIf(cond, test)
Definition: omAllocDecl.h:323
LINLINE number nlAdd(number la, number li, const coeffs r)
Definition: longrat.cc:2439
{p < 2^31}
Definition: coeffs.h:29
void nlInpGcd(number &a, number b, const coeffs r)
Definition: longrat.cc:2576
BOOLEAN nlIsMOne(number a, const coeffs r)
Definition: longrat.cc:1153
const CanonicalForm CFMap CFMap int &both_non_zero int n
Definition: cfEzgcd.cc:52
static FORCE_INLINE BOOLEAN nCoeff_is_Ring_2toM(const coeffs r)
Definition: coeffs.h:739
(), see rinteger.h, new impl.
Definition: coeffs.h:110
void nlCoeffWrite(const coeffs r, BOOLEAN details)
Definition: longrat.cc:2733
number nlIntDiv(number a, number b, const coeffs r)
Definition: longrat.cc:784
static FORCE_INLINE int n_GetChar(const coeffs r)
Return the characteristic of the coeff. domain.
Definition: coeffs.h:444
number nlGcd(number a, number b, const coeffs r)
Definition: longrat.cc:1165
factory's main class
Definition: canonicalform.h:72
#define TRUE
Definition: auxiliary.h:144
coeffs nlQuot1(number c, const coeffs r)
Definition: longrat.cc:942
#define POW_2_28
Definition: longrat.cc:105
number nlRInit(long i)
Definition: longrat.cc:2268
#define FREE_RNUMBER(x)
Definition: coeffs.h:84
number nlInit2(int i, int j, const coeffs r)
create a rational i/j (implicitly) over Q NOTE: make sure to use correct Q in debug mode ...
Definition: longrat.cc:2282
g
Definition: cfModGcd.cc:4031
const char * nlRead(const char *s, number *a, const coeffs r)
Definition: longrat0.cc:57
void WerrorS(const char *s)
Definition: feFopen.cc:23
bool negative(N n)
Definition: ValueTraits.h:119
void s_readmpz_base(s_buff F, mpz_ptr a, int base)
Definition: s_buff.cc:217
void nlGMP(number &i, number n, const coeffs r)
Definition: longrat.cc:1397
#define Q
Definition: sirandom.c:25
number nlIntMod(number a, number b, const coeffs r)
Definition: longrat.cc:850
#define POW_2_28_32
Definition: longrat.cc:106
number nlInit2gmp(mpz_t i, mpz_t j, const coeffs r)
create a rational i/j (implicitly) over Q NOTE: make sure to use correct Q in debug mode ...
Definition: longrat.cc:2295
#define WarnS
Definition: emacs.cc:81
BOOLEAN nlInitChar(coeffs r, void *p)
Definition: longrat.cc:3121
long intval() const
conversion functions
#define omAlloc(size)
Definition: omAllocDecl.h:210
void setCharacteristic(int c)
Definition: cf_char.cc:23
BOOLEAN nlGreater(number a, number b, const coeffs r)
Definition: longrat.cc:1138
LINLINE number nl_Copy(number a, const coeffs r)
void nlWrite(number &a, const coeffs r)
Definition: longrat0.cc:117
static number nlInitMPZ(mpz_t m, const coeffs)
Definition: longrat.cc:2566
CF_NO_INLINE bool isOne() const
CF_INLINE bool CanonicalForm::isOne, isZero () const.
Definition: cf_inline.cc:354
real floating point (GMP) numbers
Definition: coeffs.h:33
number nlMapZ(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:221
CanonicalForm make_cf(const mpz_ptr n)
Definition: singext.cc:67
LINLINE BOOLEAN nlIsOne(number a, const coeffs r)
Definition: longrat.cc:2362
poly res
Definition: myNF.cc:322
virtual void Reset()=0
Sets the enumerator to its initial position: -1, which is before the first element in the collection...
single prescision (6,6) real numbers
Definition: coeffs.h:31
#define MP_SMALL
Definition: longrat.cc:155
static number nlLcm(number a, number b, const coeffs r)
Definition: longrat.cc:3097
clock_t to
Definition: walk.cc:99
const ring r
Definition: syzextra.cc:208
static number nlMapP(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:191
LINLINE number nlNeg(number za, const coeffs r)
Definition: longrat.cc:2420
float nrFloat(number n)
Converts a n_R number into a float. Needed by Maps.
Definition: shortfl.cc:78
Coefficient rings, fields and other domains suitable for Singular polynomials.
void s_readmpz(s_buff F, mpz_t a)
Definition: s_buff.cc:192
const CanonicalForm CFMap CFMap & N
Definition: cfEzgcd.cc:49
number nlChineseRemainderSym(number *x, number *q, int rl, BOOLEAN sym, const coeffs CF)
Definition: longrat.cc:2741
int s_readint(s_buff F)
Definition: s_buff.cc:120
int j
Definition: myNF.cc:70
number nlDiv(number a, number b, const coeffs r)
Definition: longrat.cc:965
LINLINE number nlMult(number a, number b, const coeffs r)
Definition: longrat.cc:2475
number nlInvers(number a, const coeffs r)
Definition: longrat.cc:654
number _nlCopy_NoImm(number a)
Definition: longrat.cc:1525
#define assume(x)
Definition: mod2.h:405
void _nlInpAdd_aNoImm_OR_bNoImm(number &a, number b)
Definition: longrat.cc:1742
The main handler for Singular numbers which are suitable for Singular polynomials.
Templated enumerator interface for simple iteration over a generic collection of T's.
Definition: Enumerator.h:124
int nlDivComp(number a, number b, const coeffs r)
Definition: longrat.cc:923
LINLINE void nlInpMult(number &a, number b, const coeffs r)
Definition: longrat.cc:2523
static void nlWriteFd(number n, FILE *f, const coeffs)
Definition: longrat.cc:2977
#define A
Definition: sirandom.c:23
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition: coeffs.h:71
D(ideal gnc_gr_bba(const ideal, const ideal, const intvec *, const intvec *, kStrategy, const ring _currRing)) D(ideal gnc_gr_mora(const ideal
Modified Plural's Buchberger's algorithmus.
void _nlDelete_NoImm(number *a)
Definition: longrat.cc:1546
number nlModP(number q, const coeffs Q, const coeffs Zp)
Definition: longrat.cc:1355
virtual reference Current()=0
Gets the current element in the collection (read and write).
#define LINLINE
Definition: longrat.cc:25
static number nlMapLongR(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:433
number nlCopyMap(number a, const coeffs src, const coeffs dst)
Definition: longrat.cc:2222
static const int SW_RATIONAL
set to 1 for computations over Q
Definition: cf_defs.h:28
All the auxiliary stuff.
int m
Definition: cfEzgcd.cc:119
#define mpz_isNeg(A)
Definition: longrat.cc:157
const char *const nDivBy0
Definition: numbers.h:83
void On(int sw)
switches
LINLINE BOOLEAN nlEqual(number a, number b, const coeffs r)
Definition: longrat.cc:2335
unsigned long exp
Definition: rmodulon.h:18
void nlPower(number x, int exp, number *lu, const coeffs r)
Definition: longrat.cc:1075
#define info
Definition: libparse.cc:1254
CanonicalForm den() const
den() returns the denominator of CO if CO is a rational number, 1 (from the current domain!) otherwis...
int i
Definition: cfEzgcd.cc:123
void PrintS(const char *s)
Definition: reporter.cc:294
static number nlReadFd(s_buff f, const coeffs)
Definition: longrat.cc:3023
void nlInpIntDiv(number &a, number b, const coeffs r)
Definition: longrat.cc:2591
number nlExtGcd(number a, number b, number *s, number *t, const coeffs)
Definition: longrat.cc:2699
LINLINE BOOLEAN nlIsZero(number za, const coeffs r)
Definition: longrat.cc:2371
(mpz_ptr), see rmodulon,h
Definition: coeffs.h:113
BOOLEAN _nlEqual_aNoImm_OR_bNoImm(number a, number b)
Definition: longrat.cc:1478
number nlShort3_noinline(number x)
Definition: longrat.cc:172
static void nlClearContent(ICoeffsEnumerator &numberCollectionEnumerator, number &c, const coeffs cf)
Definition: longrat.cc:2777
static CanonicalForm nlConvSingNFactoryN(number n, const BOOLEAN setChar, const coeffs)
Definition: longrat.cc:340
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition: coeffs.h:421
int(* siRandProc)()
Definition: sirandom.h:9
number nlChineseRemainder(number *x, number *q, int rl, const coeffs C)
Definition: longrat.cc:2772
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition: cf_ops.cc:600
number nlBigInt(number &n)
#define SR_TO_INT(SR)
Definition: longrat.h:67
(number), see longrat.h
Definition: coeffs.h:109
void nlNormalize(number &x, const coeffs r)
Definition: longrat.cc:1264
void chineseRemainder(const CanonicalForm &x1, const CanonicalForm &q1, const CanonicalForm &x2, const CanonicalForm &q2, CanonicalForm &xnew, CanonicalForm &qnew)
void chineseRemainder ( const CanonicalForm & x1, const CanonicalForm & q1, const CanonicalForm & x2...
Definition: cf_chinese.cc:52
bool isImm() const
Definition: canonicalform.h:97
#define mpz_size1(A)
Definition: si_gmp.h:12
n_coeffType
Definition: coeffs.h:26
CanonicalForm cf
Definition: cfModGcd.cc:4024
number _nlNeg_NoImm(number a)
Definition: longrat.cc:1564
#define NULL
Definition: omList.c:10
static number nlShort3(number x)
Definition: longrat.cc:110
static number nlRandom(siRandProc p, number v2, number, const coeffs cf)
Definition: longrat.cc:3107
void gmp_denominator(const CanonicalForm &f, mpz_ptr result)
Definition: singext.cc:40
REvaluation E(1, terms.length(), IntRandom(25))
CanonicalForm den(const CanonicalForm &f)
LINLINE void nlDelete(number *a, const coeffs r)
Definition: longrat.cc:2404
static FORCE_INLINE number n_Div(number a, number b, const coeffs r)
return the quotient of 'a' and 'b', i.e., a/b; raises an error if 'b' is not invertible in r exceptio...
Definition: coeffs.h:613
BOOLEAN nlDivBy(number a, number b, const coeffs)
Definition: longrat.cc:909
(gmp_float), see
Definition: coeffs.h:115
b *CanonicalForm B
Definition: facBivar.cc:51
#define ABS(x)
Definition: auxiliary.h:157
virtual bool MoveNext()=0
Advances the enumerator to the next element of the collection. returns true if the enumerator was suc...
int gcd(int a, int b)
Definition: walkSupport.cc:839
BOOLEAN nlIsUnit(number a, const coeffs)
Definition: longrat.cc:956
#define R
Definition: sirandom.c:26
long nlInt(number &n, const coeffs r)
Definition: longrat.cc:604
#define SR_INT
Definition: longrat.h:65
number _nlMult_aImm_bImm_rNoImm(number a, number b)
Definition: longrat.cc:2105
#define ALLOC_RNUMBER()
Definition: coeffs.h:85
nMapFunc nlSetMap(const coeffs src, const coeffs dst)
Definition: longrat.cc:2231
Variable x
Definition: cfModGcd.cc:4023
number _nlAdd_aNoImm_OR_bNoImm(number a, number b)
Definition: longrat.cc:1576
long s_readlong(s_buff F)
Definition: s_buff.cc:148
number nlExactDiv(number a, number b, const coeffs r)
Definition: longrat.cc:733
number _nlSub_aNoImm_OR_bNoImm(number a, number b)
Definition: longrat.cc:1881
number nlMapGMP(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:208
BOOLEAN nlDBTest(number a, const char *f, const int l)
p exp[i]
Definition: DebugPrint.cc:39
LINLINE number nlInit(long i, const coeffs r)
Definition: longrat.cc:2344
#define MPZ_DIV(A, B, C)
Definition: longrat.cc:160
(int), see modulop.h
Definition: coeffs.h:108
#define SR_HDL(A)
Definition: tgb.cc:35
END_NAMESPACE const void * p2
Definition: syzextra.cc:202
static char * nlCoeffString(const coeffs r)
Definition: longrat.cc:2968
static FORCE_INLINE void n_Delete(number *p, const coeffs r)
delete 'p'
Definition: coeffs.h:455
number nlMapMachineInt(number from, const coeffs, const coeffs)
Definition: longrat.cc:233
kBucketDestroy & P
Definition: myNF.cc:191
int BOOLEAN
Definition: auxiliary.h:131
static number nlMapR(number from, const coeffs src, const coeffs dst)
Definition: longrat.cc:403
const poly b
Definition: syzextra.cc:213
number nlGetNumerator(number &n, const coeffs r)
Definition: longrat.cc:1447
LINLINE number nlCopy(number a, const coeffs r)
Definition: longrat.cc:2391
void dErrorBreak()
Definition: dError.cc:141
void Werror(const char *fmt,...)
Definition: reporter.cc:199
#define LONG
Definition: longrat.cc:107
return result
Definition: facAbsBiFact.cc:76
int l
Definition: cfEzgcd.cc:94
#define ALLOC0_RNUMBER()
Definition: coeffs.h:86
#define SSI_BASE
Definition: longrat.cc:2975
#define nlTest(a, r)
Definition: longrat.cc:89
const CanonicalForm const CanonicalForm const CanonicalForm const CanonicalForm & cand
Definition: cfModGcd.cc:69
number nlFarey(number nN, number nP, const coeffs CF)
Definition: longrat.cc:2630
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
Definition: numbers.cc:316
(float), see shortfl.h
Definition: coeffs.h:114
#define omStrDup(s)
Definition: omAllocDecl.h:263