source: git/factory/int_int.cc @ f0596e

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