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