source: git/factory/int_rat.cc @ 46b29e

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