[493c477] | 1 | /* emacs edit mode for this file is -*- C++ -*- */ |
---|
[341696] | 2 | /* $Id$ */ |
---|
[2dd068] | 3 | |
---|
[493c477] | 4 | #ifndef INCL_INT_INT_H |
---|
| 5 | #define INCL_INT_INT_H |
---|
[2dd068] | 6 | |
---|
[e4fe2b] | 7 | // #include "config.h" |
---|
[2dd068] | 8 | |
---|
[718e670] | 9 | #ifndef NOSTREAMIO |
---|
[1dc616] | 10 | #ifdef HAVE_IOSTREAM |
---|
| 11 | #include <iostream> |
---|
[181148] | 12 | #define OSTREAM std::ostream |
---|
[1dc616] | 13 | #elif defined(HAVE_IOSTREAM_H) |
---|
[2dd068] | 14 | #include <iostream.h> |
---|
[181148] | 15 | #define OSTREAM ostream |
---|
[1dc616] | 16 | #endif |
---|
[718e670] | 17 | #endif /* NOSTREAMIO */ |
---|
[2dd068] | 18 | |
---|
[650f2d8] | 19 | #include "cf_assert.h" |
---|
[718e670] | 20 | |
---|
| 21 | #include "int_cf.h" |
---|
[e4fe2b] | 22 | // #include "cf_gmp.h" |
---|
[fc732a9] | 23 | #include "gmpext.h" |
---|
[2dd068] | 24 | |
---|
[f79b94c] | 25 | #ifdef HAVE_OMALLOC |
---|
[ab58510] | 26 | #define OM_NDEBUG |
---|
[b1dfaf] | 27 | # include <omalloc/omalloc.h> |
---|
[f79b94c] | 28 | #endif |
---|
| 29 | |
---|
[2dd068] | 30 | class InternalInteger : public InternalCF |
---|
| 31 | { |
---|
| 32 | private: |
---|
| 33 | MP_INT thempi; |
---|
[fc732a9] | 34 | |
---|
| 35 | // auxilliary methods |
---|
| 36 | inline InternalCF * normalizeMyself (); |
---|
| 37 | inline InternalCF * uiNormalizeMyself (); |
---|
| 38 | |
---|
| 39 | static inline InternalCF * normalizeMPI ( MP_INT & ); |
---|
| 40 | static inline InternalCF * uiNormalizeMPI ( MP_INT & ); |
---|
| 41 | |
---|
| 42 | static inline MP_INT & MPI ( const InternalCF * const c ); |
---|
[f79b94c] | 43 | #ifdef HAVE_OMALLOC |
---|
| 44 | static const omBin InternalInteger_bin; |
---|
| 45 | #endif |
---|
[2dd068] | 46 | public: |
---|
[f79b94c] | 47 | #ifdef HAVE_OMALLOC |
---|
[0349c20] | 48 | void* operator new(size_t) |
---|
[f79b94c] | 49 | { |
---|
| 50 | void* addr; |
---|
| 51 | omTypeAllocBin(void*, addr, InternalInteger_bin); |
---|
| 52 | return addr; |
---|
| 53 | } |
---|
[0349c20] | 54 | void operator delete(void* addr, size_t) |
---|
[f79b94c] | 55 | { |
---|
| 56 | omFreeBin(addr, InternalInteger_bin); |
---|
| 57 | } |
---|
| 58 | #endif |
---|
| 59 | |
---|
[2dd068] | 60 | InternalInteger(); |
---|
| 61 | InternalInteger( const InternalCF& ) |
---|
| 62 | { |
---|
[fc11f45] | 63 | ASSERT( 0, "ups there is something wrong in your code" ); |
---|
[2dd068] | 64 | } |
---|
| 65 | InternalInteger( const int i ); |
---|
[d07137] | 66 | InternalInteger( const char * str, const int base=10 ); |
---|
[2dd068] | 67 | InternalInteger( const MP_INT & ); |
---|
| 68 | ~InternalInteger(); |
---|
| 69 | InternalCF* deepCopyObject() const; |
---|
| 70 | const char * const classname() const { return "InternalInteger"; } |
---|
[718e670] | 71 | #ifndef NOSTREAMIO |
---|
[181148] | 72 | void print( OSTREAM&, char* ); |
---|
[718e670] | 73 | #endif /* NOSTREAMIO */ |
---|
[2dd068] | 74 | InternalCF* genZero(); |
---|
| 75 | InternalCF* genOne(); |
---|
| 76 | |
---|
| 77 | bool is_imm() const; |
---|
| 78 | |
---|
| 79 | int levelcoeff() const { return IntegerDomain; } |
---|
| 80 | InternalCF* neg(); |
---|
| 81 | |
---|
| 82 | int comparesame( InternalCF* ); |
---|
| 83 | |
---|
| 84 | InternalCF* addsame( InternalCF* ); |
---|
| 85 | InternalCF* subsame( InternalCF* ); |
---|
[718e670] | 86 | InternalCF* mulsame( InternalCF* ); |
---|
[2dd068] | 87 | InternalCF* dividesame( InternalCF* ); |
---|
| 88 | InternalCF* modulosame( InternalCF* ); |
---|
[718e670] | 89 | InternalCF* divsame( InternalCF* ); |
---|
[2dd068] | 90 | InternalCF* modsame( InternalCF* ); |
---|
| 91 | void divremsame( InternalCF*, InternalCF*&, InternalCF*& ); |
---|
| 92 | bool divremsamet( InternalCF*, InternalCF*&, InternalCF*& ); |
---|
| 93 | |
---|
| 94 | int comparecoeff( InternalCF* ); |
---|
| 95 | |
---|
| 96 | InternalCF* addcoeff( InternalCF* ); |
---|
| 97 | InternalCF* subcoeff( InternalCF*, bool ); |
---|
[718e670] | 98 | InternalCF* mulcoeff( InternalCF* ); |
---|
| 99 | InternalCF* dividecoeff( InternalCF*, bool ); |
---|
[2dd068] | 100 | InternalCF* modulocoeff( InternalCF*, bool ); |
---|
[718e670] | 101 | InternalCF* divcoeff( InternalCF*, bool ); |
---|
[2dd068] | 102 | InternalCF* modcoeff( InternalCF*, bool ); |
---|
| 103 | void divremcoeff( InternalCF*, InternalCF*&, InternalCF*&, bool ); |
---|
| 104 | bool divremcoefft( InternalCF*, InternalCF*&, InternalCF*&, bool ); |
---|
| 105 | |
---|
[05d0b3] | 106 | InternalCF * bgcdsame ( const InternalCF * const ) const; |
---|
| 107 | InternalCF * bgcdcoeff ( const InternalCF * const ); |
---|
| 108 | |
---|
| 109 | InternalCF * bextgcdsame ( InternalCF *, CanonicalForm &, CanonicalForm & ); |
---|
| 110 | InternalCF * bextgcdcoeff ( InternalCF *, CanonicalForm &, CanonicalForm & ); |
---|
| 111 | |
---|
[2dd068] | 112 | int intval() const; |
---|
| 113 | |
---|
| 114 | int intmod( int p ) const; |
---|
| 115 | |
---|
| 116 | int sign() const; |
---|
| 117 | |
---|
| 118 | InternalCF* sqrt(); |
---|
| 119 | |
---|
[bd7e06a] | 120 | int ilog2(); |
---|
[fc11f45] | 121 | |
---|
[2dd068] | 122 | friend class InternalRational; |
---|
[8357930] | 123 | friend void gmp_numerator ( const CanonicalForm & f, mpz_ptr result); |
---|
| 124 | friend void gmp_denominator ( const CanonicalForm & f, mpz_ptr result ); |
---|
[2dd068] | 125 | friend MP_INT getmpi ( InternalCF * value, bool symmetric ); |
---|
| 126 | }; |
---|
| 127 | |
---|
[fc732a9] | 128 | //{{{ inline InternalCF * InternalInteger::normalizeMyself, uiNormalizeMyself () |
---|
| 129 | //{{{ docu |
---|
| 130 | // |
---|
| 131 | // normalizeMyself(), uiNormalizeMyself() - normalize CO. |
---|
| 132 | // |
---|
| 133 | // If CO fits into an immediate integer, delete CO and return the |
---|
| 134 | // immediate. Otherwise, return a pointer to CO. |
---|
| 135 | // |
---|
| 136 | // `uiNormalizeMyself()' is the same as `normalizeMyself()' |
---|
| 137 | // except that CO is expected to be non-begative. In this case, |
---|
| 138 | // we may use `mpz_get_ui()' to convert the underlying mpi into |
---|
| 139 | // an immediate which is slightly faster than the signed variant. |
---|
| 140 | // |
---|
| 141 | // Note: We do not mind reference counting at this point! CO is |
---|
| 142 | // deleted unconditionally! |
---|
| 143 | // |
---|
| 144 | //}}} |
---|
| 145 | inline InternalCF * |
---|
| 146 | InternalInteger::normalizeMyself () |
---|
| 147 | { |
---|
| 148 | ASSERT( getRefCount() == 1, "internal error: must not delete CO" ); |
---|
| 149 | |
---|
| 150 | if ( mpz_is_imm( &thempi ) ) { |
---|
[fc11f45] | 151 | InternalCF * result = int2imm( mpz_get_si( &thempi ) ); |
---|
| 152 | delete this; |
---|
| 153 | return result; |
---|
[fc732a9] | 154 | } else |
---|
[fc11f45] | 155 | return this; |
---|
[fc732a9] | 156 | } |
---|
| 157 | |
---|
| 158 | inline InternalCF * |
---|
| 159 | InternalInteger::uiNormalizeMyself () |
---|
| 160 | { |
---|
| 161 | ASSERT( getRefCount() == 1, "internal error: must not delete CO" ); |
---|
| 162 | |
---|
| 163 | if ( mpz_is_imm( &thempi ) ) { |
---|
[fc11f45] | 164 | InternalCF * result = int2imm( mpz_get_ui( &thempi ) ); |
---|
| 165 | delete this; |
---|
| 166 | return result; |
---|
[fc732a9] | 167 | } else |
---|
[fc11f45] | 168 | return this; |
---|
[fc732a9] | 169 | } |
---|
| 170 | //}}} |
---|
| 171 | |
---|
| 172 | //{{{ static inline InternalCF * InternalInteger::normalizeMPI, uiNormalizeMPI ( MP_INT & aMpi ) |
---|
| 173 | //{{{ docu |
---|
| 174 | // |
---|
| 175 | // normalizeMPI(), uiNormalizeMPI() - normalize a mpi. |
---|
| 176 | // |
---|
| 177 | // If `aMpi' fits into an immediate integer, clear `aMpi' and |
---|
| 178 | // return the immediate. Otherwise, return a new |
---|
| 179 | // `InternalInteger' with `aMpi' as underlying mpi. |
---|
| 180 | // |
---|
| 181 | // `uiNormalizeMPI()' is the same as `normalizeMPI()' except that |
---|
| 182 | // `aMpi' is expected to be non-begative. In this case, we may |
---|
| 183 | // use `mpz_get_ui()' to convert `aMpi' into an immediate which |
---|
| 184 | // is slightly faster than the signed variant. |
---|
| 185 | // |
---|
| 186 | //}}} |
---|
| 187 | inline InternalCF * |
---|
| 188 | InternalInteger::normalizeMPI ( MP_INT & aMpi ) |
---|
| 189 | { |
---|
| 190 | if ( mpz_is_imm( &aMpi ) ) { |
---|
[fc11f45] | 191 | InternalCF * result = int2imm( mpz_get_si( &aMpi ) ); |
---|
| 192 | mpz_clear( &aMpi ); |
---|
| 193 | return result; |
---|
[fc732a9] | 194 | } else |
---|
[fc11f45] | 195 | return new InternalInteger( aMpi ); |
---|
[fc732a9] | 196 | } |
---|
| 197 | |
---|
| 198 | inline InternalCF * |
---|
| 199 | InternalInteger::uiNormalizeMPI ( MP_INT & aMpi ) |
---|
| 200 | { |
---|
| 201 | if ( mpz_is_imm( &aMpi ) ) { |
---|
[fc11f45] | 202 | InternalCF * result = int2imm( mpz_get_ui( &aMpi ) ); |
---|
| 203 | mpz_clear( &aMpi ); |
---|
| 204 | return result; |
---|
[fc732a9] | 205 | } else |
---|
[fc11f45] | 206 | return new InternalInteger( aMpi ); |
---|
[fc732a9] | 207 | } |
---|
| 208 | //}}} |
---|
| 209 | |
---|
| 210 | //{{{ inline MP_INT & InternalInteger::MPI ( const InternalCF * const c ) |
---|
| 211 | //{{{ docu |
---|
| 212 | // |
---|
| 213 | // MPI() - return underlying mpi of `c'. |
---|
| 214 | // |
---|
| 215 | // `c' is expected to be an `InternalInteger *'. `c's underlying |
---|
| 216 | // mpi is returned. |
---|
| 217 | // |
---|
| 218 | //}}} |
---|
| 219 | inline MP_INT & |
---|
| 220 | InternalInteger::MPI ( const InternalCF * const c ) |
---|
[2dd068] | 221 | { |
---|
| 222 | return (((InternalInteger*)c)->thempi); |
---|
| 223 | } |
---|
[fc732a9] | 224 | //}}} |
---|
[2dd068] | 225 | |
---|
[493c477] | 226 | #endif /* ! INCL_INT_INT_H */ |
---|