int_rat.cc
Go to the documentation of this file.
1 /* emacs edit mode for this file is -*- C++ -*- */
2 
3 
4 #include "config.h"
5 
6 
7 #include "cf_assert.h"
8 
9 #include "cf_defs.h"
10 #include "int_rat.h"
11 #include "int_int.h"
12 #include "imm.h"
13 #include "canonicalform.h"
14 #include "cf_factory.h"
15 #include "gmpext.h"
16 
17 static long intgcd( long a, long b )
18 {
19  if ( a < 0 ) a = -a;
20  if ( b < 0 ) b = -b;
21 
22  long c;
23 
24  while ( b != 0 )
25  {
26  c = a % b;
27  a = b;
28  b = c;
29  }
30  return a;
31 }
32 
33 
35 {
36  mpz_init( _num );
37  mpz_init_set_si( _den, 1 );
38 }
39 
41 {
42  mpz_init_set_si( _num, i );
43  mpz_init_set_si( _den, 1 );
44 }
45 
46 InternalRational::InternalRational( const int n, const int d )
47 {
48  ASSERT( d != 0, "divide by zero" );
49  if ( n == 0 )
50  {
51  mpz_init_set_si( _num, 0 );
52  mpz_init_set_si( _den, 1 );
53  }
54  else
55  {
56  long g = intgcd( (long) n, (long) d );
57  if ( d < 0 )
58  {
59  mpz_init_set_si( _num, -((long)n) / g );
60  mpz_init_set_si( _den, -((long)d) / g );
61  }
62  else
63  {
64  mpz_init_set_si( _num, n / g );
65  mpz_init_set_si( _den, d / g );
66  }
67  }
68 }
69 
71 {
72  mpz_init_set_si( _num, i );
73  mpz_init_set_si( _den, 1 );
74 }
75 
76 InternalRational::InternalRational( const long n, const long d )
77 {
78  ASSERT( d != 0, "divide by zero" );
79  if ( n == 0 )
80  {
81  mpz_init_set_si( _num, 0 );
82  mpz_init_set_si( _den, 1 );
83  }
84  else
85  {
86  long g = intgcd( n, d );
87  if ( d < 0 )
88  {
89  mpz_init_set_si( _num, -n / g );
90  mpz_init_set_si( _den, -d / g );
91  }
92  else
93  {
94  mpz_init_set_si( _num, n / g );
95  mpz_init_set_si( _den, d / g );
96  }
97  }
98 }
99 
101 {
102  // sollte nicht gebraucht werden !!!
103  ASSERT( 0, "fatal error" );
104  mpz_init( _num );
105  mpz_init( _den );
106 }
107 
108 //InternalRational::InternalRational( const mpz_ptr n ) : _num(n)
109 //{
110 // mpz_init_set_si( _den, 1 );
111 //}
112 
114 {
115  _num[0]=*n;
116  mpz_init_set_si( _den, 1 );
117 }
118 
119 InternalRational::InternalRational( const mpz_ptr n, const mpz_ptr d )
120 {
121  _num[0]=*n;
122  _den[0]=*d;
123 }
124 
126 {
127  mpz_clear( _num );
128  mpz_clear( _den );
129 }
130 
132 {
133  mpz_t dummy_num;
134  mpz_t dummy_den;
135  mpz_init_set( dummy_num, _num );
136  mpz_init_set( dummy_den, _den );
137  return new InternalRational( dummy_num, dummy_den );
138 }
139 
140 #ifndef NOSTREAMIO
141 void InternalRational::print( OSTREAM & os, char * c )
142 {
143  char * str = new char[mpz_sizeinbase( _num, 10 ) + 2];
144  str = mpz_get_str( str, 10, _num );
145  os << str << '/';
146  delete [] str;
147  str = new char[mpz_sizeinbase( _den, 10 ) + 2];
148  str = mpz_get_str( str, 10, _den );
149  os << str << c;
150  delete [] str;
151 }
152 #endif /* NOSTREAMIO */
153 
155 {
156  return mpz_cmp_si( _den, 1 ) == 0 && mpz_is_imm( _num );
157 }
158 
160 {
161  if ( isZero() )
162  return copyObject();
163  else
164  return new InternalRational();
165 }
166 
168 {
169  if ( isOne() )
170  return copyObject();
171  else
172  return new InternalRational( 1 );
173 }
174 
175 /**
176  * @sa CanonicalForm::num(), CanonicalForm::den(), InternalRational::den()
177 **/
179 {
180  if ( mpz_is_imm( _num ) )
181  {
182  InternalCF * res = int2imm( mpz_get_si( _num ) );
183  return res;
184  }
185  else
186  {
187  mpz_t dummy;
188  mpz_init_set( dummy, _num );
189  return new InternalInteger( dummy );
190  }
191 }
192 
193 /**
194  * @sa CanonicalForm::num(), CanonicalForm::den(), InternalRational::num()
195 **/
197 {
198  if ( mpz_is_imm( _den ) )
199  {
200  InternalCF * res = int2imm( mpz_get_si( _den ) );
201  return res;
202  }
203  else
204  {
205  mpz_t dummy;
206  mpz_init_set( dummy, _den );
207  return new InternalInteger( dummy );
208  }
209 }
210 
211 /** InternalCF * InternalRational::neg ()
212  * @sa CanonicalForm::operator -()
213 **/
214 InternalCF *
216 {
217  if ( getRefCount() > 1 )
218  {
219  decRefCount();
220  mpz_t dummy_num;
221  mpz_t dummy_den;
222  mpz_init_set( dummy_num, _num );
223  mpz_init_set( dummy_den, _den );
224  mpz_neg( dummy_num, dummy_num );
225  return new InternalRational( dummy_num, dummy_den );
226  }
227  else
228  {
229  mpz_neg( _num, _num );
230  return this;
231  }
232 }
233 
235 {
236  ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
237  mpz_t n, d, g;
238 
239  mpz_init( g ); mpz_init( n ); mpz_init( d );
240  mpz_gcd( g, _den, MPQDEN( c ) );
241 
242  if ( mpz_cmp_si( g, 1 ) == 0 )
243  {
244  mpz_mul( n, _den, MPQNUM( c ) );
245  mpz_mul( g, _num, MPQDEN( c ) );
246  mpz_add( n, n, g );
247  mpz_mul( d, _den, MPQDEN( c ) );
248  }
249  else
250  {
251  mpz_t tmp1;
252  mpz_t tmp2;
253  mpz_init( tmp1 );
254  mpz_divexact( tmp1, _den, g );
255  mpz_init( tmp2 );
256  mpz_divexact( tmp2, MPQDEN( c ), g );
257  mpz_mul( d, tmp2, _den );
258  mpz_mul( tmp2, tmp2, _num );
259  mpz_mul( tmp1, tmp1, MPQNUM( c ) );
260  mpz_add( n, tmp1, tmp2 );
261  mpz_gcd( g, n, d );
262  if ( mpz_cmp_si( g, 1 ) != 0 )
263  {
264  mpz_divexact( n, n, g );
265  mpz_divexact( d, d, g );
266  }
267  mpz_clear( tmp1 );
268  mpz_clear( tmp2 );
269  }
270  mpz_clear( g );
271  if ( deleteObject() ) delete this;
272  if ( mpz_cmp_si( d, 1 ) == 0 )
273  {
274  mpz_clear( d );
275  if ( mpz_is_imm( n ) )
276  {
277  InternalCF * res = int2imm( mpz_get_si( n ) );
278  mpz_clear( n );
279  return res;
280  }
281  else
282  {
283  return new InternalInteger( n );
284  }
285  }
286  else
287  {
288  return new InternalRational( n, d );
289  }
290 }
291 
293 {
294  ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
295  mpz_t n, d, g;
296 
297  mpz_init( g ); mpz_init( n ); mpz_init( d );
298  mpz_gcd( g, _den, MPQDEN( c ) );
299 
300  if ( mpz_cmp_si( g, 1 ) == 0 )
301  {
302  mpz_mul( n, _den, MPQNUM( c ) );
303  mpz_mul( g, _num, MPQDEN( c ) );
304  mpz_sub( n, g, n );
305  mpz_mul( d, _den, MPQDEN( c ) );
306  }
307  else
308  {
309  mpz_t tmp1;
310  mpz_t tmp2;
311  mpz_init( tmp1 );
312  mpz_divexact( tmp1, _den, g );
313  mpz_init( tmp2 );
314  mpz_divexact( tmp2, MPQDEN( c ), g );
315  mpz_mul( d, tmp2, _den );
316  mpz_mul( tmp2, tmp2, _num );
317  mpz_mul( tmp1, tmp1, MPQNUM( c ) );
318  mpz_sub( n, tmp2, tmp1 );
319  mpz_gcd( g, n, d );
320  if ( mpz_cmp_si( g, 1 ) != 0 )
321  {
322  mpz_divexact( n, n, g );
323  mpz_divexact( d, d, g );
324  }
325  mpz_clear( tmp1 );
326  mpz_clear( tmp2 );
327  }
328  mpz_clear( g );
329  if ( deleteObject() ) delete this;
330  if ( mpz_cmp_si( d, 1 ) == 0 )
331  {
332  mpz_clear( d );
333  if ( mpz_is_imm( n ) )
334  {
335  InternalCF * res = int2imm( mpz_get_si( n ) );
336  mpz_clear( n );
337  return res;
338  }
339  else
340  {
341  return new InternalInteger( n );
342  }
343  }
344  else
345  return new InternalRational( n, d );
346 }
347 
349 {
350  ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
351  mpz_t n, d;
352  mpz_init( n ); mpz_init( d );
353 
354  if ( this == c )
355  {
356  mpz_mul( n, _num, _num );
357  mpz_mul( d, _den, _den );
358  }
359  else
360  {
361  mpz_t g1, g2, tmp1, tmp2;
362  mpz_init( g1 ); mpz_init( g2 );
363  mpz_gcd( g1, _num, MPQDEN( c ) );
364  mpz_gcd( g2, _den, MPQNUM( c ) );
365  bool g1is1 = mpz_cmp_si( g1, 1 ) == 0;
366  bool g2is1 = mpz_cmp_si( g2, 1 ) == 0;
367  mpz_init( tmp1 ); mpz_init( tmp2 );
368  if ( ! g1is1 )
369  mpz_divexact( tmp1, _num, g1 );
370  else
371  mpz_set( tmp1, _num );
372  if ( ! g2is1 )
373  mpz_divexact( tmp2, MPQNUM( c ), g2 );
374  else
375  mpz_set( tmp2, MPQNUM( c ) );
376  mpz_mul( n, tmp1, tmp2 );
377  if ( ! g1is1 )
378  mpz_divexact( tmp1, MPQDEN( c ), g1 );
379  else
380  mpz_set( tmp1, MPQDEN( c ) );
381  if ( ! g2is1 )
382  mpz_divexact( tmp2, _den, g2 );
383  else
384  mpz_set( tmp2, _den );
385  mpz_mul( d, tmp1, tmp2 );
386  mpz_clear( tmp1 ); mpz_clear( tmp2 );
387  mpz_clear( g1 ); mpz_clear( g2 );
388  }
389  if ( deleteObject() ) delete this;
390  if ( mpz_cmp_si( d, 1 ) == 0 )
391  {
392  mpz_clear( d );
393  if ( mpz_is_imm( n ) )
394  {
395  InternalCF * res = int2imm( mpz_get_si( n ) );
396  mpz_clear( n );
397  return res;
398  }
399  else
400  {
401  return new InternalInteger( n );
402  }
403  }
404  else
405  return new InternalRational( n, d );
406 }
407 
409 {
410  ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
411 
412  if ( this == c )
413  {
414  if ( deleteObject() ) delete this;
415  return CFFactory::basic( 1L );
416  }
417  else
418  {
419  mpz_t n, d;
420  mpz_t g1, g2, tmp1, tmp2;
421  mpz_init( n ); mpz_init( d );
422  mpz_init( g1 ); mpz_init( g2 );
423  mpz_gcd( g1, _num, MPQNUM( c ) );
424  mpz_gcd( g2, _den, MPQDEN( c ) );
425  bool g1is1 = mpz_cmp_si( g1, 1 ) == 0;
426  bool g2is1 = mpz_cmp_si( g2, 1 ) == 0;
427  mpz_init( tmp1 ); mpz_init( tmp2 );
428  if ( ! g1is1 )
429  mpz_divexact( tmp1, _num, g1 );
430  else
431  mpz_set( tmp1, _num );
432  if ( ! g2is1 )
433  mpz_divexact( tmp2, MPQDEN( c ), g2 );
434  else
435  mpz_set( tmp2, MPQDEN( c ) );
436  mpz_mul( n, tmp1, tmp2 );
437  if ( ! g1is1 )
438  mpz_divexact( tmp1, MPQNUM( c ), g1 );
439  else
440  mpz_set( tmp1, MPQNUM( c ) );
441  if ( ! g2is1 )
442  mpz_divexact( tmp2, _den, g2 );
443  else
444  mpz_set( tmp2, _den );
445  mpz_mul( d, tmp1, tmp2 );
446  mpz_clear( tmp1 ); mpz_clear( tmp2 );
447  mpz_clear( g1 ); mpz_clear( g2 );
448  if ( deleteObject() ) delete this;
449  if ( mpz_cmp_si( d, 0 ) < 0 )
450  {
451  mpz_neg( d, d );
452  mpz_neg( n, n );
453  }
454  if ( mpz_cmp_si( d, 1 ) == 0 )
455  {
456  mpz_clear( d );
457  if ( mpz_is_imm( n ) )
458  {
459  InternalCF * res = int2imm( mpz_get_si( n ) );
460  mpz_clear( n );
461  return res;
462  }
463  else
464  {
465  return new InternalInteger( n );
466  }
467  }
468  else
469  return new InternalRational( n, d );
470  }
471 }
472 
474 {
475  return dividesame( c );
476 }
477 
479 {
480  return modsame( c );
481 }
482 
484 {
485  if ( deleteObject() ) delete this;
486  return CFFactory::basic( 0L );
487 }
488 
490 {
491  quot = copyObject();
492  quot = quot->dividesame( c );
493  rem = CFFactory::basic( 0L );
494 }
495 
497 {
498  divremsame( c, quot, rem );
499  return true;
500 }
501 
502 /**
503  * comparesame(), comparecoeff() - compare with an
504  * InternalRational.
505  *
506  * comparesame() compares the CO=a/b and c=p/q using the
507  * equivalence a/b < p/q iff a*q < p*b.
508  *
509  * Note: May be relatively expensive due to the
510  * multiplications.
511  *
512  * See also: CanonicalForm::operator <(), CanonicalForm::operator ==()
513  *
514 **/
515 int
517 {
518  ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "incompatible base coefficients" );
519  mpz_t dummy1, dummy2;
520  mpz_init( dummy1 ); mpz_init( dummy2 );
521  mpz_mul( dummy1, _num, MPQDEN( c ) );
522  mpz_mul( dummy2, _den, MPQNUM( c ) );
523  int result = mpz_cmp( dummy1, dummy2 );
524  mpz_clear( dummy1 ); mpz_clear( dummy2 );
525  return result;
526 }
527 
528 /**
529  * comparecoeff() compares the CO=a/b and the integer c using the
530  * equivalence a/b < c iff a < c*b.
531  *
532  * Note: May be relatively expensive due to the
533  * multiplications.
534 **/
535 int
537 {
538  if ( ::is_imm( c ) )
539  {
540  ASSERT( ::is_imm( c ) == INTMARK, "incompatible base coefficients" );
541  mpz_t dummy;
542  mpz_init_set_si( dummy, imm2int( c ) );
543  mpz_mul( dummy, dummy, _den );
544  int result = mpz_cmp( _num, dummy );
545  mpz_clear( dummy );
546  return result;
547  }
548  else
549  {
550  ASSERT( c->levelcoeff() == IntegerDomain, "incompatible base coefficients" );
551  mpz_t dummy;
552  mpz_init( dummy );
553  mpz_mul( dummy, _den, InternalInteger::MPI( c ) );
554  int result = mpz_cmp( _num, dummy );
555  mpz_clear( dummy );
556  return result;
557  }
558 }
559 
561 {
562  ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
563  mpz_t n, d;
564  if ( ::is_imm( c ) )
565  {
566  long cc = imm2int( c );
567  if ( cc == 0 )
568  return this;
569  else
570  {
571  mpz_init( n );
572  if ( cc < 0 )
573  {
574  mpz_mul_ui( n, _den, -cc );
575  mpz_sub( n, _num, n );
576  }
577  else
578  {
579  mpz_mul_ui( n, _den, cc );
580  mpz_add( n, _num, n );
581  }
582  }
583  }
584  else
585  {
586  ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
587  mpz_init( n );
588  mpz_mul( n, _den, InternalInteger::MPI( c ) );
589  mpz_add( n, _num, n );
590  }
591  mpz_init_set( d, _den );
592  // at this point there is no way that the result is not a true rational
593  if ( deleteObject() ) delete this;
594  return new InternalRational( n, d );
595 }
596 
598 {
599  ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
600  mpz_t n, d;
601  if ( ::is_imm( c ) )
602  {
603  long cc = imm2int( c );
604  if ( cc == 0 )
605  {
606  if ( negate )
607  {
608  if ( getRefCount() == 1 )
609  {
610  mpz_neg( _num, _num );
611  return this;
612  }
613  else
614  {
615  decRefCount();
616  mpz_init_set( d, _den );
617  mpz_init_set( n, _num );
618  mpz_neg( n, n );
619  return new InternalRational( n, d );
620  }
621  }
622  else
623  return this;
624  }
625  mpz_init( n );
626  if ( cc < 0 )
627  {
628  mpz_mul_ui( n, _den, -cc );
629  mpz_neg( n, n );
630  }
631  else
632  mpz_mul_ui( n, _den, cc );
633  if ( negate )
634  mpz_sub( n, n, _num );
635  else
636  mpz_sub( n, _num, n );
637  }
638  else
639  {
640  ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
641  mpz_init( n );
642  mpz_mul( n, _den, InternalInteger::MPI( c ) );
643  if ( negate )
644  mpz_sub( n, n, _num );
645  else
646  mpz_sub( n, _num, n );
647  }
648  mpz_init_set( d, _den );
649  // at this point there is no way that the result is not a true rational
650  if ( deleteObject() ) delete this;
651  return new InternalRational( n, d );
652 }
653 
655 {
656  ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
657  mpz_t n, d, g;
658  if ( ::is_imm( c ) )
659  {
660  long cc = imm2int( c );
661  if ( cc == 0 )
662  {
663  if ( deleteObject() ) delete this;
664  return CFFactory::basic( 0L );
665  }
666  mpz_init_set_si( n, cc );
667  }
668  else
669  {
670  ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
671  mpz_init_set( n, InternalInteger::MPI( c ) );
672  }
673  mpz_init( g );
674  mpz_gcd( g, n, _den );
675  if ( mpz_cmp_si( g, 1 ) == 0 )
676  {
677  mpz_mul( n, n, _num );
678  mpz_init_set( d, _den );
679  }
680  else
681  {
682  mpz_divexact( n, n, g );
683  mpz_mul( n, n, _num );
684  mpz_init( d );
685  mpz_divexact( d, _den, g );
686  }
687  mpz_clear( g );
688  if ( deleteObject() ) delete this;
689  if ( mpz_cmp_si( d, 1 ) == 0 )
690  {
691  mpz_clear( d );
692  if ( mpz_is_imm( n ) )
693  {
694  InternalCF * res = int2imm( mpz_get_si( n ) );
695  mpz_clear( n );
696  return res;
697  }
698  else
699  {
700  return new InternalInteger( n );
701  }
702  }
703  else
704  return new InternalRational( n, d );
705 }
706 
708 {
709  ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
710  mpz_t n, d, g;
711  if ( ::is_imm( c ) )
712  {
713  long cc = imm2int( c );
714  ASSERT( c != 0 || invert, "divide by zero" );
715  if ( cc == 0 )
716  {
717  // => invert
718  if ( deleteObject() ) delete this;
719  return CFFactory::basic( 0L );
720  }
721  if ( invert )
722  {
723  mpz_init_set_si( n, cc );
724  mpz_mul( n, n, _den );
725  mpz_init_set( d, _num );
726  }
727  else
728  {
729  mpz_init_set_si( d, cc );
730  mpz_mul( d, d, _den );
731  mpz_init_set( n, _num );
732  }
733  }
734  else
735  {
736  ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
737  if ( invert )
738  {
739  mpz_init_set( n, InternalInteger::MPI( c ) );
740  mpz_mul( n, n, _den );
741  mpz_init_set( d, _num );
742  }
743  else
744  {
745  mpz_init_set( d, InternalInteger::MPI( c ) );
746  mpz_mul( d, d, _den );
747  mpz_init_set( n, _num );
748  }
749  }
750  if ( mpz_cmp_si( d, 0 ) < 0 )
751  {
752  mpz_neg( d, d );
753  mpz_neg( n, n );
754  }
755  mpz_init( g );
756  mpz_gcd( g, n, d );
757  if ( mpz_cmp_si( g, 1 ) != 0 )
758  {
759  mpz_divexact( d, d, g );
760  mpz_divexact( n, n, g );
761  }
762  mpz_clear( g );
763  if ( deleteObject() ) delete this;
764  if ( ! invert )
765  {
766  // then there was no way for the result to become an integer
767  return new InternalRational( n, d );
768  }
769  if ( mpz_cmp_si( d, 1 ) == 0 )
770  {
771  mpz_clear( d );
772  if ( mpz_is_imm( n ) )
773  {
774  InternalCF * res = int2imm( mpz_get_si( n ) );
775  mpz_clear( n );
776  return res;
777  }
778  else
779  {
780  return new InternalInteger( n );
781  }
782  }
783  else
784  return new InternalRational( n, d );
785 }
786 
788 {
789  return dividecoeff( c, invert );
790 }
791 
793 {
794  return modcoeff( c, invert );
795 }
796 
798 {
799  ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "integer expected" );
800  ASSERT( invert || ! ::is_imm( c ) || imm2int( c ) != 0, "divide by zero" );
801  if ( deleteObject() ) delete this;
802  return CFFactory::basic( 0L );
803 }
804 
806 {
807  quot = copyObject();
808  quot = quot->dividecoeff( c, invert );
809  rem = CFFactory::basic( 0L );
810 }
811 
813 {
814  divremcoeff( c, quot, rem, invert );
815  return true;
816 }
817 
818 /**
819  * @sa CanonicalForm::bgcd(), InternalRational::bgcdcoeff()
820 **/
821 InternalCF *
822 InternalRational::bgcdsame ( const InternalCF * const ) const
823 {
824  return int2imm( 1 );
825 }
826 
827 /**
828  * @sa CanonicalForm::bgcd(), InternalRational::bgcdsame()
829 **/
830 InternalCF *
832 {
833  return int2imm( 1 );
834 }
835 
836 /**
837  * @sa CanonicalForm::bextgcd(), InternalRational::bextgcdcoeff()
838 **/
839 InternalCF *
841 {
842  a = 1/CanonicalForm( copyObject() ); b = 0;
843  return int2imm( 1 );
844 }
845 
846 /**
847  * @sa CanonicalForm::bextgcd(), InternalRational::bextgcdsame()
848 **/
849 InternalCF *
851 {
852  a = 1/CanonicalForm( copyObject() ); b = 0;
853  return int2imm( 1 );
854 }
855 
856 /**
857  * reduce InternalRational to lowest terms
858 **/
860 {
861  ASSERT( getRefCount() == 1, "illegal operation" );
862  mpz_t g;
863  mpz_init( g );
864  mpz_gcd( g, _num, _den );
865  if ( mpz_cmp_si( g, 1 ) != 0 )
866  {
867  mpz_divexact( _num, _num, g );
868  mpz_divexact( _den, _den, g );
869  }
870  mpz_clear( g );
871  if ( mpz_cmp_si( _den, 0 ) < 0 )
872  {
873  mpz_neg( _num, _num );
874  mpz_neg( _den, _den );
875  }
876  if ( mpz_cmp_si( _den, 1 ) == 0 )
877  {
878  if ( mpz_is_imm( _num ) )
879  {
880  InternalCF * res = int2imm( mpz_get_si( _num ) );
881  delete this;
882  return res;
883  }
884  else
885  {
886  mpz_t res;
887  mpz_init_set( res, _num );
888  delete this;
889  return new InternalInteger( res );
890  }
891  }
892  else
893  return this;
894 }
895 
896 
898 {
899 
900  ASSERT( mpz_cmp_si( _den, 1 ) == 0, "illegal operation" );
901  return mpz_get_si( _num );
902 
903 }
904 
905 /**
906  * @sa CanonicalForm::sign()
907 **/
908 int
910 {
911  return mpz_sgn( _num );
912 }
InternalCF * modcoeff(InternalCF *, bool)
Definition: int_rat.cc:797
friend class InternalInteger
Definition: int_rat.h:114
InternalCF * deepCopyObject() const
Definition: int_rat.cc:131
Factory&#39;s internal rationals.
int deleteObject()
Definition: int_cf.h:57
InternalCF * mulcoeff(InternalCF *)
Definition: int_rat.cc:654
InternalCF * den()
Definition: int_rat.cc:196
virtual bool isOne() const
bool InternalCF::isOne, isZero () const
Definition: int_cf.cc:18
int decRefCount()
Definition: int_cf.h:49
void rem(unsigned long *a, unsigned long *q, unsigned long p, int &dega, int degq)
Definition: minpoly.cc:574
const poly a
Definition: syzextra.cc:212
InternalCF * addsame(InternalCF *)
Definition: int_rat.cc:234
int comparesame(InternalCF *)
comparesame(), comparecoeff() - compare with an InternalRational.
Definition: int_rat.cc:516
InternalCF * mulsame(InternalCF *)
Definition: int_rat.cc:348
void divremcoeff(InternalCF *, InternalCF *&, InternalCF *&, bool)
Definition: int_rat.cc:805
InternalCF * normalize_myself()
reduce InternalRational to lowest terms
Definition: int_rat.cc:859
InternalCF * int2imm(long i)
Definition: imm.h:71
void divremsame(InternalCF *, InternalCF *&, InternalCF *&)
Definition: int_rat.cc:489
InternalCF * addcoeff(InternalCF *)
Definition: int_rat.cc:560
bool divremcoefft(InternalCF *, InternalCF *&, InternalCF *&, bool)
Definition: int_rat.cc:812
InternalCF * dividecoeff(InternalCF *, bool)
Definition: int_rat.cc:707
InternalCF * bextgcdsame(InternalCF *, CanonicalForm &, CanonicalForm &)
Definition: int_rat.cc:840
InternalCF * copyObject()
Definition: int_cf.h:58
factory&#39;s main class
Definition: canonicalform.h:75
InternalCF * bgcdcoeff(const InternalCF *const)
Definition: int_rat.cc:831
assertions for Factory
g
Definition: cfModGcd.cc:4031
InternalCF * genOne()
Definition: int_rat.cc:167
static mpz_ptr MPQDEN(const InternalCF *const c)
Definition: int_rat.h:125
virtual bool isZero() const
Definition: int_cf.cc:24
virtual class for internal CanonicalForm&#39;s
Definition: int_cf.h:39
#define IntegerDomain
Definition: cf_defs.h:25
virtual int levelcoeff() const
Definition: int_cf.h:64
poly res
Definition: myNF.cc:322
InternalCF * genZero()
Definition: int_rat.cc:159
InternalCF * neg()
InternalCF * InternalRational::neg ()
Definition: int_rat.cc:215
InternalCF * num()
Definition: int_rat.cc:178
Interface to generate InternalCF&#39;s over various domains from intrinsic types or mpz_t&#39;s.
InternalCF * subcoeff(InternalCF *, bool)
Definition: int_rat.cc:597
long intval() const
Definition: int_rat.cc:897
int comparecoeff(InternalCF *)
comparecoeff() compares the CO=a/b and the integer c using the equivalence a/b < c iff a < c*b...
Definition: int_rat.cc:536
InternalCF * dividesame(InternalCF *)
Definition: int_rat.cc:408
InternalCF * bgcdsame(const InternalCF *const) const
Definition: int_rat.cc:822
void print(OSTREAM &, char *)
Definition: int_rat.cc:141
int sign() const
Definition: int_rat.cc:909
virtual InternalCF * dividesame(InternalCF *) PVIRT_INTCF("dividesame")
InternalCF * divsame(InternalCF *)
Definition: int_rat.cc:473
int i
Definition: cfEzgcd.cc:123
virtual InternalCF * dividecoeff(InternalCF *, bool) PVIRT_INTCF("dividecoeff")
static InternalCF * basic(long value)
Definition: cf_factory.cc:21
InternalCF * modulosame(InternalCF *)
Definition: int_rat.cc:478
factory switches.
#define RationalDomain
Definition: cf_defs.h:24
static mpz_ptr MPI(const InternalCF *const c)
MPI() - return underlying mpz_t of `c&#39;.
Definition: int_int.h:232
CFList tmp2
Definition: facFqBivar.cc:70
virtual InternalCF * invert()
Definition: int_cf.cc:172
long imm2int(const InternalCF *const imm)
Definition: imm.h:66
utility functions for gmp
bool is_imm() const
Definition: int_rat.cc:154
CFList tmp1
Definition: facFqBivar.cc:70
InternalCF * subsame(InternalCF *)
Definition: int_rat.cc:292
operations on immediates, that is elements of F_p, GF, Z, Q that fit into intrinsic int...
bool divremsamet(InternalCF *, InternalCF *&, InternalCF *&)
Definition: int_rat.cc:496
InternalCF * modulocoeff(InternalCF *, bool)
Definition: int_rat.cc:792
#define OSTREAM
Definition: canonicalform.h:16
const long INTMARK
Definition: imm.h:37
static long intgcd(long a, long b)
Definition: int_rat.cc:17
InternalCF * modsame(InternalCF *)
Definition: int_rat.cc:483
#define ASSERT(expression, message)
Definition: cf_assert.h:99
bool mpz_is_imm(const mpz_t mpi)
Definition: gmpext.h:20
const poly b
Definition: syzextra.cc:213
InternalCF * bextgcdcoeff(InternalCF *, CanonicalForm &, CanonicalForm &)
Definition: int_rat.cc:850
InternalCF * divcoeff(InternalCF *, bool)
Definition: int_rat.cc:787
return result
Definition: facAbsBiFact.cc:76
static mpz_ptr MPQNUM(const InternalCF *const c)
Definition: int_rat.h:120
Header for factory&#39;s main class CanonicalForm.
Factory&#39;s internal integers.
int getRefCount()
Definition: int_cf.h:47