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