source: git/factory/int_int.h @ eebdf2

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