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