source: git/factory/int_rat.cc @ 72dd6e

spielwiese
Last change on this file since 72dd6e was 493c477, checked in by Jens Schmidt <schmidt@…>, 27 years ago
o header fixed git-svn-id: file:///usr/local/Singular/svn/trunk@404 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 17.0 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: int_rat.cc,v 1.3 1997-06-19 12:22:27 schmidt Exp $ */
3
4#include <config.h>
5
6#include "assert.h"
7
8#include "cf_defs.h"
9#include "cf_globals.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
17static int intgcd( int a, int b )
18{
19    if ( a < 0 ) a = -a;
20    if ( b < 0 ) b = -b;
21
22    int c;
23
24    while ( b != 0 ) {
25        c = a % b;
26        a = b;
27        b = c;
28    }
29    return a;
30}
31
32
33InternalRational::InternalRational()
34{
35    mpz_init( &_num );
36    mpz_init_set_si( &_den, 1 );
37}
38
39InternalRational::InternalRational( const int i )
40{
41    mpz_init_set_si( &_num, i );
42    mpz_init_set_si( &_den, 1 );
43}
44
45InternalRational::InternalRational( const int n, const int d )
46{
47    ASSERT( d != 0, "divide by zero" );
48    if ( n == 0 ) {
49        mpz_init_set_si( &_num, 0 );
50        mpz_init_set_si( &_den, 1 );
51    }
52    else {
53        int g = intgcd( n, d );
54        if ( d < 0 ) {
55            mpz_init_set_si( &_num, -n / g );
56            mpz_init_set_si( &_den, -d / g );
57        }
58        else {
59            mpz_init_set_si( &_num, n / g );
60            mpz_init_set_si( &_den, d / g );
61        }
62    }
63}
64
65InternalRational::InternalRational( const char * )
66{
67    // sollte nicht gebraucht werden !!!
68    ASSERT( 0, "fatal error" );
69    mpz_init( &_num );
70    mpz_init( &_den );
71}
72
73InternalRational::InternalRational( const MP_INT &n ) : _num(n)
74{
75    mpz_init_set_si( &_den, 1 );
76}
77
78InternalRational::InternalRational( const MP_INT &n, const MP_INT &d ) : _num(n), _den(d)
79{
80}
81
82InternalRational::~InternalRational()
83{
84    mpz_clear( &_num );
85    mpz_clear( &_den );
86}
87
88InternalCF* InternalRational::deepCopyObject() const
89{
90    MP_INT dummy_num;
91    MP_INT dummy_den;
92    mpz_init_set( &dummy_num, &_num );
93    mpz_init_set( &dummy_den, &_den );
94    return new InternalRational( dummy_num, dummy_den );
95}
96
97#ifndef NOSTREAMIO
98void InternalRational::print( ostream & os, char * c )
99{
100    char * str = new char[mpz_sizeinbase( &_num, 10 ) + 2];
101    str = mpz_get_str( str, 10, &_num );
102    os << str << '/';
103    delete [] str;
104    str = new char[mpz_sizeinbase( &_den, 10 ) + 2];
105    str = mpz_get_str( str, 10, &_den );
106    os << str << c;
107    delete [] str;
108}
109#endif /* NOSTREAMIO */
110
111bool InternalRational::isZero() const
112{
113    return mpz_cmp_si( &_num, 0 ) == 0;
114}
115
116bool InternalRational::isOne() const
117{
118    return mpz_cmp_si( &_den, 1 ) == 0 && mpz_cmp_si( &_num, 1 ) == 0;
119}
120
121bool InternalRational::is_imm() const
122{
123    return mpz_cmp_si( &_den, 1 ) == 0 && mpz_is_imm( &_num );
124}
125
126InternalCF* InternalRational::genZero()
127{
128    if ( isZero() )
129        return copyObject();
130    else
131        return new InternalRational();
132}
133
134InternalCF* InternalRational::genOne()
135{
136    if ( isOne() )
137        return copyObject();
138    else
139        return new InternalRational( 1 );
140}
141
142InternalCF* InternalRational::num()
143{
144    if ( mpz_is_imm( &_num ) ) {
145        InternalCF * res = int2imm( mpz_get_si( &_num ) );
146        return res;
147    }
148    else {
149        MP_INT dummy;
150        mpz_init_set( &dummy, &_num );
151        return new InternalInteger( dummy );
152    }
153}
154
155InternalCF* InternalRational::den()
156{
157    if ( mpz_is_imm( &_den ) ) {
158        InternalCF * res = int2imm( mpz_get_si( &_den ) );
159        return res;
160    }
161    else {
162        MP_INT dummy;
163        mpz_init_set( &dummy, &_den );
164        return new InternalInteger( dummy );
165    }
166}
167
168InternalCF* InternalRational::neg()
169{
170    if ( getRefCount() > 1 ) {
171        decRefCount();
172        MP_INT dummy_num;
173        MP_INT dummy_den;
174        mpz_init_set( &dummy_num, &_num );
175        mpz_init_set( &dummy_den, &_den );
176        mpz_neg( &dummy_num, &dummy_num );
177        return new InternalRational( dummy_num, dummy_den );
178    }
179    else {
180        mpz_neg( &_num, &_num );
181        return this;
182    }
183}
184
185int InternalRational::comparesame( InternalCF * c )
186{
187    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
188    MP_INT dummy1, dummy2;
189    mpz_init( &dummy1 ); mpz_init( &dummy2 );
190    mpz_mul( &dummy1, &_num, &MPQDEN( c ) );
191    mpz_mul( &dummy2, &_den, &MPQNUM( c ) );
192    int result = mpz_cmp( &dummy1, &dummy2 );
193    mpz_clear( &dummy1 ); mpz_clear( &dummy2 );
194    return result;
195}
196
197InternalCF* InternalRational::addsame( InternalCF * c )
198{
199    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
200    MP_INT n, d, g;
201
202    mpz_init( &g ); mpz_init( &n ); mpz_init( &d );
203    mpz_gcd( &g, &_den, &MPQDEN( c ) );
204
205    if ( mpz_cmp_si( &g, 1 ) == 0 ) {
206        mpz_mul( &n, &_den, &MPQNUM( c ) );
207        mpz_mul( &g, &_num, &MPQDEN( c ) );
208        mpz_add( &n, &n, &g );
209        mpz_mul( &d, &_den, &MPQDEN( c ) );
210    }
211    else {
212        MP_INT tmp1;
213        MP_INT tmp2;
214        mpz_init( &tmp1 );
215        mpz_div( &tmp1, &_den, &g );
216        mpz_init( &tmp2 );
217        mpz_div( &tmp2, &MPQDEN( c ), &g );
218        mpz_mul( &d, &tmp2, &_den );
219        mpz_mul( &tmp2, &tmp2, &_num );
220        mpz_mul( &tmp1, &tmp1, &MPQNUM( c ) );
221        mpz_add( &n, &tmp1, &tmp2 );
222        mpz_gcd( &g, &n, &d );
223        if ( mpz_cmp_si( &g, 1 ) != 0 ) {
224            mpz_div( &n, &n, &g );
225            mpz_div( &d, &d, &g );
226        }
227        mpz_clear( &tmp1 );
228        mpz_clear( &tmp2 );
229    }
230    mpz_clear( &g );
231    if ( deleteObject() ) delete this;
232    if ( mpz_cmp_si( &d, 1 ) == 0 ) {
233        if ( mpz_is_imm( &n ) ) {
234            InternalCF * res = int2imm( mpz_get_si( &n ) );
235            mpz_clear( &n ); mpz_clear( &d );
236            return res;
237        }
238        else {
239            mpz_clear( &d );
240            return new InternalInteger( n );
241        }
242    }
243    else
244        return new InternalRational( n, d );
245}
246
247InternalCF* InternalRational::subsame( InternalCF * c )
248{
249    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
250    MP_INT n, d, g;
251
252    mpz_init( &g ); mpz_init( &n ); mpz_init( &d );
253    mpz_gcd( &g, &_den, &MPQDEN( c ) );
254
255    if ( mpz_cmp_si( &g, 1 ) == 0 ) {
256        mpz_mul( &n, &_den, &MPQNUM( c ) );
257        mpz_mul( &g, &_num, &MPQDEN( c ) );
258        mpz_sub( &n, &g, &n );
259        mpz_mul( &d, &_den, &MPQDEN( c ) );
260    }
261    else {
262        MP_INT tmp1;
263        MP_INT tmp2;
264        mpz_init( &tmp1 );
265        mpz_div( &tmp1, &_den, &g );
266        mpz_init( &tmp2 );
267        mpz_div( &tmp2, &MPQDEN( c ), &g );
268        mpz_mul( &d, &tmp2, &_den );
269        mpz_mul( &tmp2, &tmp2, &_num );
270        mpz_mul( &tmp1, &tmp1, &MPQNUM( c ) );
271        mpz_sub( &n, &tmp2, &tmp1 );
272        mpz_gcd( &g, &n, &d );
273        if ( mpz_cmp_si( &g, 1 ) != 0 ) {
274            mpz_div( &n, &n, &g );
275            mpz_div( &d, &d, &g );
276        }
277        mpz_clear( &tmp1 );
278        mpz_clear( &tmp2 );
279    }
280    mpz_clear( &g );
281    if ( deleteObject() ) delete this;
282    if ( mpz_cmp_si( &d, 1 ) == 0 ) {
283        if ( mpz_is_imm( &n ) ) {
284            InternalCF * res = int2imm( mpz_get_si( &n ) );
285            mpz_clear( &n ); mpz_clear( &d );
286            return res;
287        }
288        else {
289            mpz_clear( &d );
290            return new InternalInteger( n );
291        }
292    }
293    else
294        return new InternalRational( n, d );
295}
296
297InternalCF* InternalRational::mulsame( InternalCF * c )
298{
299    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
300    MP_INT n, d;
301
302    if ( this == c ) {
303        mpz_init( &n ); mpz_init( &d );
304        mpz_mul( &n, &_num, &_num );
305        mpz_mul( &d, &_den, &_den );
306    }
307    else {
308        MP_INT g1, g2, tmp1, tmp2;
309        mpz_init( &g1 ); mpz_init( &g2 );
310        mpz_init( &n ); mpz_init( &d );
311        mpz_gcd( &g1, &_num, &MPQDEN( c ) );
312        mpz_gcd( &g2, &_den, &MPQNUM( c ) );
313        bool g1is1 = mpz_cmp_si( &g1, 1 ) == 0;
314        bool g2is1 = mpz_cmp_si( &g2, 1 ) == 0;
315        mpz_init( &tmp1 ); mpz_init( &tmp2 );
316        if ( ! g1is1 )
317            mpz_div( &tmp1, &_num, &g1 );
318        else
319            mpz_set( &tmp1, &_num );
320        if ( ! g2is1 )
321            mpz_div( &tmp2, &MPQNUM( c ), &g2 );
322        else
323            mpz_set( &tmp2, &MPQNUM( c ) );
324        mpz_mul( &n, &tmp1, &tmp2 );
325        if ( ! g1is1 )
326            mpz_div( &tmp1, &MPQDEN( c ), &g1 );
327        else
328            mpz_set( &tmp1, &MPQDEN( c ) );
329        if ( ! g2is1 )
330            mpz_div( &tmp2, &_den, &g2 );
331        else
332            mpz_set( &tmp2, &_den );
333        mpz_mul( &d, &tmp1, &tmp2 );
334        mpz_clear( &tmp1 ); mpz_clear( &tmp2 );
335        mpz_clear( &g1 ); mpz_clear( &g2 );
336    }
337    if ( deleteObject() ) delete this;
338    if ( mpz_cmp_si( &d, 1 ) == 0 ) {
339        if ( mpz_is_imm( &n ) ) {
340            InternalCF * res = int2imm( mpz_get_si( &n ) );
341            mpz_clear( &n ); mpz_clear( &d );
342            return res;
343        }
344        else {
345            mpz_clear( &d );
346            return new InternalInteger( n );
347        }
348    }
349    else
350        return new InternalRational( n, d );
351}
352
353InternalCF* InternalRational::dividesame( InternalCF * c )
354{
355    ASSERT( ! ::is_imm( c ) && c->levelcoeff() == RationalDomain, "illegal domain" );
356
357    if ( this == c ) {
358        if ( deleteObject() ) delete this;
359        return CFFactory::basic( 1 );
360    }
361    else {
362        MP_INT n, d;
363        MP_INT g1, g2, tmp1, tmp2;
364        mpz_init( &n ); mpz_init( &d );
365        mpz_init( &g1 ); mpz_init( &g2 );
366        mpz_gcd( &g1, &_num, &MPQNUM( c ) );
367        mpz_gcd( &g2, &_den, &MPQDEN( c ) );
368        bool g1is1 = mpz_cmp_si( &g1, 1 ) == 0;
369        bool g2is1 = mpz_cmp_si( &g2, 1 ) == 0;
370        mpz_init( &tmp1 ); mpz_init( &tmp2 );
371        if ( ! g1is1 )
372            mpz_div( &tmp1, &_num, &g1 );
373        else
374            mpz_set( &tmp1, &_num );
375        if ( ! g2is1 )
376            mpz_div( &tmp2, &MPQDEN( c ), &g2 );
377        else
378            mpz_set( &tmp2, &MPQDEN( c ) );
379        mpz_mul( &n, &tmp1, &tmp2 );
380        if ( ! g1is1 )
381            mpz_div( &tmp1, &MPQNUM( c ), &g1 );
382        else
383            mpz_set( &tmp1, &MPQNUM( c ) );
384        if ( ! g2is1 )
385            mpz_div( &tmp2, &_den, &g2 );
386        else
387            mpz_set( &tmp2, &_den );
388        mpz_mul( &d, &tmp1, &tmp2 );
389        mpz_clear( &tmp1 ); mpz_clear( &tmp2 );
390        mpz_clear( &g1 ); mpz_clear( &g2 );
391        if ( deleteObject() ) delete this;
392        if ( mpz_cmp_si( &d, 0 ) < 0 ) {
393            mpz_neg( &d, &d );
394            mpz_neg( &n, &n );
395        }
396        if ( mpz_cmp_si( &d, 1 ) == 0 ) {
397            if ( mpz_is_imm( &n ) ) {
398                InternalCF * res = int2imm( mpz_get_si( &n ) );
399                mpz_clear( &n ); mpz_clear( &d );
400                return res;
401            }
402            else {
403                mpz_clear( &d );
404                return new InternalInteger( n );
405            }
406        }
407        else
408            return new InternalRational( n, d );
409    }
410}
411
412InternalCF* InternalRational::divsame( InternalCF * c )
413{
414    return dividesame( c );
415}
416
417InternalCF* InternalRational::modulosame( InternalCF * c )
418{
419    return modsame( c );
420}
421
422InternalCF* InternalRational::modsame( InternalCF * )
423{
424    if ( deleteObject() ) delete this;
425    return CFFactory::basic( 0 );
426}
427
428void InternalRational::divremsame( InternalCF * c, InternalCF*& quot, InternalCF*& rem )
429{
430    quot = copyObject();
431    quot = quot->dividesame( c );
432    rem = CFFactory::basic( 0 );
433}
434
435bool InternalRational::divremsamet( InternalCF* c, InternalCF*& quot, InternalCF*& rem )
436{
437    divremsame( c, quot, rem );
438    return true;
439}
440
441int InternalRational::comparecoeff( InternalCF* c )
442{
443    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
444    if ( ::is_imm( c ) ) {
445        MP_INT dummy;
446        mpz_init_set_si( &dummy, imm2int( c ) );
447        mpz_mul( &dummy, &dummy, &_den );
448        int result = mpz_cmp( &_num, &dummy );
449        mpz_clear( &dummy );
450        return result;
451    }
452    else {
453        ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
454        MP_INT dummy;
455        mpz_init( &dummy );
456        mpz_mul( &dummy, &dummy, &InternalInteger::MPI( c ) );
457        int result = mpz_cmp( &_num, &dummy );
458        mpz_clear( &dummy );
459        return result;
460    }
461}
462
463InternalCF* InternalRational::addcoeff( InternalCF* c )
464{
465    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
466    MP_INT n, d;
467    if ( ::is_imm( c ) ) {
468        int cc = imm2int( c );
469        if ( cc == 0 )
470            return this;
471        else  if ( cc < 0 ) {
472            mpz_init( &n );
473            mpz_mul_ui( &n, &_den, -cc );
474            mpz_sub( &n, &_num, &n );
475        }
476        else {
477            mpz_init( &n );
478            mpz_mul_ui( &n, &_den, cc );
479            mpz_add( &n, &_num, &n );
480        }
481    }
482    else {
483        ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
484        mpz_init( &n );
485        mpz_mul( &n, &_den, &InternalInteger::MPI( c ) );
486        mpz_add( &n, &_num, &n );
487    }
488    mpz_init_set( &d, &_den );
489    // at this point there is no way that the result is not a true rational
490    if ( deleteObject() ) delete this;
491    return new InternalRational( n, d );
492}
493
494InternalCF* InternalRational::subcoeff( InternalCF* c, bool negate )
495{
496    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
497    MP_INT n, d;
498    if ( ::is_imm( c ) ) {
499        int cc = imm2int( c );
500        if ( cc == 0 )
501            if ( negate ) {
502                if ( getRefCount() == 1 ) {
503                    mpz_neg( &_num, &_num );
504                    return this;
505                }
506                else {
507                    decRefCount();
508                    mpz_init_set( &d, &_den );
509                    mpz_init_set( &n, &_num );
510                    mpz_neg( &n, &n );
511                    return new InternalRational( n, d );
512                }
513            }
514            else
515                return this;
516        mpz_init( &n );
517        if ( cc < 0 ) {
518            mpz_mul_ui( &n, &_den, -cc );
519            mpz_neg( &n, &n );
520        }
521        else
522            mpz_mul_ui( &n, &_den, cc );
523        if ( negate )
524            mpz_sub( &n, &n, &_num );
525        else
526            mpz_sub( &n, &_num, &n );
527    }
528    else {
529        ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
530        mpz_init( &n );
531        mpz_mul( &n, &_den, &InternalInteger::MPI( c ) );
532        if ( negate )
533            mpz_sub( &n, &n, &_num );
534        else
535            mpz_sub( &n, &_num, &n );
536    }
537    mpz_init_set( &d, &_den );
538    // at this point there is no way that the result is not a true rational
539    if ( deleteObject() ) delete this;
540    return new InternalRational( n, d );
541}
542
543InternalCF* InternalRational::mulcoeff( InternalCF* c )
544{
545    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
546    MP_INT n, d, g;
547    if ( ::is_imm( c ) ) {
548        int cc = imm2int( c );
549        if ( cc == 0 ) {
550            if ( deleteObject() ) delete this;
551            return CFFactory::basic( 0 );
552        }
553        mpz_init_set_si( &n, cc );
554    }
555    else {
556        ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
557        mpz_init_set( &n, &InternalInteger::MPI( c ) );
558    }
559    mpz_init( &g );
560    mpz_gcd( &g, &n, &_den );
561    if ( mpz_cmp_si( &g, 1 ) == 0 ) {
562        mpz_mul( &n, &n, &_num );
563        mpz_init_set( &d, &_den );
564    }
565    else {
566        mpz_div( &n, &n, &g );
567        mpz_mul( &n, &n, &_num );
568        mpz_init( &d );
569        mpz_div( &d, &_den, &g );
570    }
571    mpz_clear( &g );
572    if ( deleteObject() ) delete this;
573    if ( mpz_cmp_si( &d, 1 ) == 0 ) {
574        if ( mpz_is_imm( &n ) ) {
575            InternalCF * res = int2imm( mpz_get_si( &n ) );
576            mpz_clear( &n ); mpz_clear( &d );
577            return res;
578        }
579        else {
580            mpz_clear( &d );
581            return new InternalInteger( n );
582        }
583    }
584    else
585        return new InternalRational( n, d );
586}
587
588InternalCF* InternalRational::dividecoeff( InternalCF* c, bool invert )
589{
590    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "expected integer" );
591    MP_INT n, d, g;
592    if ( ::is_imm( c ) ) {
593        int cc = imm2int( c );
594        ASSERT( c != 0 || invert, "divide by zero" );
595        if ( cc == 0 ) {
596            // => invert
597            if ( deleteObject() ) delete this;
598            return CFFactory::basic( 0 );
599        }
600        if ( invert ) {
601            mpz_init_set_si( &n, cc );
602            mpz_mul( &n, &n, &_den );
603            mpz_init_set( &d, &_num );
604        }
605        else {
606            mpz_init_set_si( &d, cc );
607            mpz_mul( &d, &d, &_den );
608            mpz_init_set( &n, &_num );
609        }
610    }
611    else {
612        ASSERT( c->levelcoeff() == IntegerDomain, "expected integer" );
613        if ( invert ) {
614            mpz_init_set( &n, &InternalInteger::MPI( c ) );
615            mpz_mul( &n, &n, &_den );
616            mpz_init_set( &d, &_num );
617        }
618        else {
619            mpz_init_set( &d, &InternalInteger::MPI( c ) );
620            mpz_mul( &d, &d, &_den );
621            mpz_init_set( &n, &_num );
622        }
623    }
624    if ( mpz_cmp_si( &d, 0 ) < 0 ) {
625        mpz_neg( &d, &d );
626        mpz_neg( &n, &n );
627    }
628    mpz_init( &g );
629    mpz_gcd( &g, &n, &d );
630    if ( mpz_cmp_si( &g, 1 ) != 0 ) {
631        mpz_div( &d, &d, &g );
632        mpz_div( &n, &n, &g );
633    }
634    mpz_clear( &g );
635    if ( deleteObject() ) delete this;
636    if ( ! invert ) {
637        // then there was no way for the result to become an integer
638        return new InternalRational( n, d );
639    }
640    if ( mpz_cmp_si( &d, 1 ) == 0 ) {
641        if ( mpz_is_imm( &n ) ) {
642            InternalCF * res = int2imm( mpz_get_si( &n ) );
643            mpz_clear( &n ); mpz_clear( &d );
644            return res;
645        }
646        else {
647            mpz_clear( &d );
648            return new InternalInteger( n );
649        }
650    }
651    else
652        return new InternalRational( n, d );
653}
654
655InternalCF* InternalRational::divcoeff( InternalCF* c, bool invert )
656{
657    return dividecoeff( c, invert );
658}
659
660InternalCF* InternalRational::modulocoeff( InternalCF* c, bool invert )
661{
662    return modcoeff( c, invert );
663}
664
665InternalCF* InternalRational::modcoeff( InternalCF* c, bool invert )
666{
667    ASSERT( ::is_imm( c ) == INTMARK || ! ::is_imm( c ), "integer expected" );
668    ASSERT( invert || ! ::is_imm( c ) || imm2int( c ) != 0, "divide by zero" );
669    if ( deleteObject() ) delete this;
670    return CFFactory::basic( 0 );
671}
672
673void InternalRational::divremcoeff( InternalCF* c, InternalCF*& quot, InternalCF*& rem, bool invert )
674{
675    quot = copyObject();
676    quot = quot->dividecoeff( c, invert );
677    rem = CFFactory::basic( 0 );
678}
679
680bool InternalRational::divremcoefft( InternalCF* c, InternalCF*& quot, InternalCF*& rem, bool invert )
681{
682    divremcoeff( c, quot, rem, invert );
683    return true;
684}
685
686InternalCF * InternalRational::normalize_myself()
687{
688    ASSERT( getRefCount() == 1, "illegal operation" );
689    MP_INT g;
690    mpz_init( &g );
691    mpz_gcd( &g, &_num, &_den );
692    if ( mpz_cmp_si( &g, 1 ) != 0 ) {
693        mpz_div( &_num, &_num, &g );
694        mpz_div( &_den, &_den, &g );
695    }
696    if ( mpz_cmp_si( &_den, 0 ) < 0 ) {
697        mpz_neg( &_num, &_num );
698        mpz_neg( &_den, &_den );
699    }
700    if ( mpz_cmp_si( &_den, 1 ) == 0 )
701        if ( mpz_is_imm( &_num ) ) {
702            InternalCF * res = int2imm( mpz_get_si( &_num ) );
703            delete this;
704            return res;
705        }
706        else {
707            MP_INT res;
708            mpz_init_set( &res, &_num );
709            delete this;
710            return new InternalInteger( res );
711        }
712    else
713        return this;
714}
715
716
717int InternalRational::intval() const
718{
719    ASSERT( mpz_cmp_si( &_den, 1 ) == 0, "illegal operation" );
720    return (int)mpz_get_si( &_num );
721}
722
723// int InternalRational::intmod( int p ) const
724// {
725//   return (int)mpz_mmod_ui( 0, &thempq, (unsigned long)p );
726// }
727
728int InternalRational::sign ( ) const
729{
730    return mpz_cmp_si( &_num, 0 );
731}
Note: See TracBrowser for help on using the repository browser.