00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030
00031
00032
00033 #ifndef VALUE_H
00034 #define VALUE_H
00035
00036
00037 #ifdef __GNUG__
00038 #pragma interface "Value.h"
00039 #endif
00040
00041
00042 #include "mc/Setup.h"
00043 #include <math.h>
00044
00045
00046 #ifdef mcUSE_GMP
00047
00048 #include <gmp.h>
00049
00050 #else
00051
00052
00053
00054 typedef struct { double val; } __mpf_struct;
00055 #define __mpq_struct __mpf_struct
00056 #define __mpz_struct __mpf_struct
00057 #define mp_exp_t int
00058
00059 typedef __mpz_struct* mpz_t;
00060 typedef const __mpz_struct* mpz_src;
00061 typedef __mpq_struct* mpq_t;
00062 typedef const __mpq_struct* mpq_src;
00063 typedef __mpf_struct* mpf_t;
00064 typedef const __mpq_struct* mpf_src;
00065
00066
00067
00068
00069 static unsigned long mpf_get_ui(mpf_src op) { return op.val; }
00070 static void mpf_set_z(mpf_t op, mpz_src t) { op.val = t.val; }
00071 static void mpf_set_q(mpf_t op, mpq_src t) { op.val = t.val; }
00072 static void mpf_init(mpf_t op) { op.val = 0; }
00073 static void mpf_clear(mpf_t op) { op.val = 0; }
00074 static void mpf_set(mpf_t op, mpf_src t) { op.val = t.val; }
00075 static void mpf_set_ui(mpf_t op, unsigned long newval) { op.val = newval; }
00076 static void mpf_set_str(mpf_t op, const char *str, int) { op.val = atoi(str); }
00077 static void mpf_abs(mpf_t op, mpf_src t) { op.val = abs(t.val); }
00078 static void mpf_pow_ui(mpf_t op, mpf_src base, unsigned long exp) { op.val = pow(base.val, exp); }
00079 static void mpf_floor(mpf_t op, mpf_src t) { op.val = floor(t.val); }
00080 static void mpf_ceil(mpf_t op, mpf_src t) { op.val = ceil(t.val); }
00081 static void mpf_trunc(mpf_t op, mpf_src t) { op.val = ceil(t.val); }
00082 static void mpf_add_ui(mpf_t op, mpf_src t, unsigned long add) { op.val = t.val + add; }
00083 static void mpf_sub_ui(mpf_t op, mpf_src t, unsigned long add) { op.val = t.val - add; }
00084 static void mpf_add(mpf_t op, mpf_src t, mpf_src add) { op.val = t.val + add.val; }
00085 static void mpf_sub(mpf_t op, mpf_src t, mpf_src add) { op.val = t.val - add.val; }
00086 static void mpf_mul(mpf_t op, mpf_src t, mpf_src add) { op.val = t.val * add.val; }
00087 static void mpf_div(mpf_t op, mpf_src t, mpf_src add) { op.val = t.val / add.val; }
00088 static void mpf_set_d(mpf_t op, double t) { op.val = t; }
00089 static double mpf_get_d(mpf_src op) { return op.val; }
00090 static int mpf_integer_p(mpf_src op) { return ceil(op.val) == floor(op.val); }
00091
00092 static int mpf_cmp_d(mpf_src op, double op2) { if (op.val > op2) return 1;
00093 if (op.val == op2) return 0;
00094 return -1; }
00095 static int mpf_cmp_si(mpf_src op, long op2) { return mpf_cmp_d(op, (double)op2); }
00096 static int mpf_cmp(mpf_src op, mpf_src op2) { return mpf_cmp_d(op, op2.val); }
00097
00098 static char *mpf_get_str(char *str, int *exp, int base, int digits, mpf_src op) { return wxT(""); }
00099
00100 static void mp_set_memory_functions (
00101 static void *(*alloc_func_ptr) (size_t),
00102 static void *(*realloc_func_ptr) (static void *, size_t, size_t),
00103 static void (*free_func_ptr) (static void *, size_t)) {}
00104
00105
00106
00107
00108
00109 #define mpz_init mpf_init
00110 #define mpz_clear mpf_clear
00111 #define mpz_set mpf_set
00112 #define mpz_set_ui mpf_set_ui
00113 #define mpz_get_ui mpf_get_ui
00114 #define mpz_set_str mpf_set_str
00115 #define mpz_abs mpf_abs
00116 #define mpz_pow_ui mpf_pow_ui
00117
00118 static void mpz_gcd(mpz_t res, mpz_src, mpz_src) { res.val = 0; }
00119 static void mpz_lcm(mpz_t res, mpz_src, mpz_src) { res.val = 0; }
00120 static void mpz_set_q(mpz_t res, mpq_src d) { res.val = d.val; }
00121 static void mpz_set_f(mpz_t res, mpf_src d) { res.val = d.val; }
00122 static int mpz_sizeinbase(mpf_src d, int) { return 10; }
00123 static char *mpz_get_str(char *str, int, mpz_src op) { return wxT(""); }
00124
00125
00126
00127
00128
00129 #define mpq_init mpf_init
00130 #define mpq_clear mpf_clear
00131 #define mpq_set mpf_set
00132 #define mpq_get_ui mpf_get_ui
00133 #define mpq_set_str mpf_set_str
00134 #define mpq_abs mpf_abs
00135
00136 static void mpq_get_den(mpz_t op, mpq_src) { op.val = 1; }
00137 static void mpq_get_num(mpz_t op, mpq_src t) { op.val = t.val; }
00138 static void mpq_set_d(mpq_t op, double d) { op.val = d; }
00139 static void mpq_set_z(mpq_t op, mpz_src d) { op.val = d.val; }
00140 static void mpq_set_f(mpq_t op, mpf_src d) { op.val = d.val; }
00141 static void mpq_canonicalize(mpz_t) {}
00142 static void mpq_set_ui(mpz_t op, unsigned long n, unsigned long d) { op.val = n/d; }
00143 static double mpq_get_d(mpq_src op) { return op.val; }
00144
00145 #endif
00146
00147
00148
00150 #define mcVALUE_DEFAULTPRECISION 30
00151
00153 #define mcVALUE_SMARTSTR_THRESHOLD 10
00154
00155 #if wxUSE_UNICODE
00156 #define WX2GMP(x) (wxString(x).mb_str(wxConvUTF8).data())
00157 #else
00158 #define WX2GMP(x) (wxString(x).mb_str(wxConvUTF8))
00159 #endif
00160
00161 #define GMP2WX(x) (wxString(x, wxConvUTF8))
00162
00163
00164
00165
00166 class mcIntegerValue;
00167 class mcRationalValue;
00168 class mcRealValue;
00169 class mcComplexValue;
00170
00171
00175 void *mcGMPAlloc(size_t n);
00176
00180 void *mcGMPRealloc(void *p, size_t oldsz, size_t newsz);
00181
00184 void mcGMPFree(void *, size_t);
00185
00186
00187
00188
00191
00194 #define mcVALUE_MASK 0xFFFF0000
00195
00196 #define mcVALUE_NAN_FLAG 0x000F
00197 #define mcVALUE_POSINF_FLAG 0x00F0
00198 #define mcVALUE_NEGINF_FLAG 0x0F00
00199
00203 #define mcVALUE_DEFINE_GMP_STRUCTWRAPPER(name, base) \
00204 struct name : base { \
00205 wxUint32 flags; \
00206 \
00207 void SetRefCount(wxUint16 n) \
00208 { flags = (n & ~mcVALUE_MASK) | (GetFlags()<<16); } \
00209 wxUint16 GetRefCount() const \
00210 { return (wxUint16)(flags & ~mcVALUE_MASK); } \
00211 void SetFlags(wxUint16 n) \
00212 { flags = (((int)n) << 16) | GetRefCount(); } \
00213 wxUint16 GetFlags() const \
00214 { return (wxUint16)(flags >> 16); } \
00215 };
00216
00217 mcVALUE_DEFINE_GMP_STRUCTWRAPPER(mcMPF, __mpf_struct);
00218 mcVALUE_DEFINE_GMP_STRUCTWRAPPER(mcMPQ, __mpq_struct);
00219 mcVALUE_DEFINE_GMP_STRUCTWRAPPER(mcMPZ, __mpz_struct);
00220
00222
00223
00224
00229
00233 #define mcVALUE_DEFINE_INTERNALS(x, fncprefix) \
00234 void InternalInit(int flags = 0) { \
00235 mp = new x; fncprefix##_init(mp); \
00236 mp->SetRefCount((wxUint16)1); \
00237 mp->SetFlags((wxInt16)flags); } \
00238 void InternalDestroy() \
00239 { fncprefix##_clear(mp); delete mp; }
00240
00243 #define mcVALUE_DEFINE_REFCOUNT(x, y) \
00244 \
00245 x *mp; \
00246 \
00247 void CopyMP(const x *n) { \
00248 mcASSERT(mp != NULL, \
00249 wxT("This object is not initialized")); \
00250 y##_set(mp, n); \
00251 mp->flags = n->flags; \
00252 } \
00253 \
00254 \
00255 void Ref(x *p) { \
00256 mcASSERT(p->GetRefCount() > 0, \
00257 wxT("This object cannot exist")); \
00258 p->SetRefCount((wxUint16)(p->GetRefCount()+1)); \
00259 } \
00260 \
00261 \
00262 \
00263 void Unref() { \
00264 mcASSERT(mp->GetRefCount() > 0, \
00265 wxT("This object cannot exist")); \
00266 \
00267 if (mp) \
00268 m_nMaxValueSharing = mcMAX(m_nMaxValueSharing, \
00269 mp->GetRefCount()); \
00270 \
00271 mp->SetRefCount((wxUint16)(mp->GetRefCount()-1)); \
00272 if (mp->GetRefCount() == 0) \
00273 InternalDestroy(); \
00274 }
00275
00278 #define mcVALUE_DEFINE_INTERNAL_GETTERS(x) \
00279 \
00280 x *MP() { \
00281 mcASSERT(mp->GetRefCount() > 0, \
00282 wxT("This object cannot exist")); \
00283 if (mp->GetRefCount() == 1) \
00284 return mp; \
00285 \
00286 \
00287 x *old = mp; \
00288 Unref(); \
00289 InternalInit(); \
00290 CopyMP(old); \
00291 return mp; \
00292 } \
00293 \
00294 \
00295 \
00296 const x *cMP() const { \
00297 return mp; \
00298 }
00299
00301 #define mcVALUE_DEFINE_SETGET_FLAGS() \
00302 int GetFlags() const { return (int)cMP()->GetFlags(); } \
00303 void SetFlags(int n) { MP()->SetFlags((wxInt16)n); } \
00304 bool hasSameFlags(int n) const { return GetFlags() == n; }
00305
00307 #define mcVALUE_DEFINE_SETTERS(x, fncprefix) \
00308 void SetLong(long n) { fncprefix##_set_si(MP(), n); } \
00309 void SetStr(const wxString &str, int base = 10) \
00310 { fncprefix##_set_str(MP(), WX2GMP(str), base); }
00311
00313 #define mcVALUE_DEFINE_GETTERS(x, fncprefix) \
00314 long GetLong() const { return fncprefix##_get_ui(cMP()); }
00315
00319 #define mcVALUE_DEFINE_MISCELLANEOUS(rettype, fncprefix) \
00320 rettype ChangeSign() \
00321 { rettype ret; fncprefix##_neg(ret.MP(), cMP()); return ret; }
00322
00324 #define mcVALUE_DEFINE_GETSET(x, fncprefix) \
00325 mcVALUE_DEFINE_SETGET_FLAGS() \
00326 mcVALUE_DEFINE_GETTERS(x, fncprefix) \
00327 mcVALUE_DEFINE_SETTERS(x, fncprefix)
00328
00329 #define mcVALUE_DEFINE_FLAGS_EQUAL_OPERATORS(y, fnc, z) \
00330 bool operator==(y m) const {return (fnc(cMP(), z) == 0) && hasSameFlags(m.GetFlags());} \
00331 bool operator!=(y m) const {return (fnc(cMP(), z) != 0) || !hasSameFlags(m.GetFlags());}
00332
00333 #define mcVALUE_DEFINE_NOFLAGS_EQUAL_OPERATORS(y, fnc, z) \
00334 bool operator==(y m) const {return (fnc(cMP(), z) == 0);} \
00335 bool operator!=(y m) const {return (fnc(cMP(), z) != 0);}
00336
00338 #define mcVALUE_DEFINE_NOFLAGS_GTLT_OPERATORS(y, fnc, z) \
00339 bool operator<=(y m) const {return (fnc(cMP(), z) <= 0);} \
00340 bool operator>=(y m) const {return (fnc(cMP(), z) >= 0);} \
00341 bool operator<(y m) const {return (fnc(cMP(), z) < 0);} \
00342 bool operator>(y m) const {return (fnc(cMP(), z) > 0);}
00343
00344 #define mcVALUE_DEFINE_NOFLAGSCOMPARISON_OPERATORS(y, fnc, z) \
00345 mcVALUE_DEFINE_NOFLAGS_GTLT_OPERATORS(y, fnc, z) \
00346 mcVALUE_DEFINE_NOFLAGS_EQUAL_OPERATORS(y, fnc, z)
00347
00348 #define mcVALUE_DEFINE_FLAGSCOMPARISON_OPERATORS(y, fnc, z) \
00349 mcVALUE_DEFINE_NOFLAGS_GTLT_OPERATORS(y, fnc, z) \
00350 mcVALUE_DEFINE_FLAGS_EQUAL_OPERATORS(y, fnc, z)
00351
00353 #define mcVALUE_DEFINE_ARITHMETIC_OPERATORS(rettype, x, y, fncprefix, z, w) \
00354 friend rettype operator+(x a, y b) \
00355 {rettype ret; fncprefix##_add(ret.MP(), z, w); return ret;} \
00356 friend rettype operator-(x a, y b) \
00357 {rettype ret; fncprefix##_sub(ret.MP(), z, w); return ret;} \
00358 friend rettype operator*(x a, y b) \
00359 {rettype ret; fncprefix##_mul(ret.MP(), z, w); return ret;} \
00360 friend rettype operator/(x a, y b) \
00361 {rettype ret; fncprefix##_div(ret.MP(), z, w); return ret;}
00362
00364 #define mcVALUE_DEFINE_UNARY_OPERATORS(rettype, x, fncprefix) \
00365 rettype &operator=(const rettype &m) { Unref(); mp=m.mp; Ref(mp); return *this;} \
00366 rettype &operator=(x &m) { mp=&m; Ref(mp); return *this;} \
00367 rettype &operator=(const wxString &str) { SetStr(str); return *this;} \
00368 rettype &operator=(int n) { SetInt(n); return *this;} \
00369 rettype operator++() { fncprefix##_add_ui(MP(), cMP(), 1); return *this;} \
00370 rettype operator--() { fncprefix##_sub_ui(MP(), cMP(), 1); return *this;} \
00371 rettype &operator+=(const rettype &m) {*this = *this+m;return *this;} \
00372 rettype &operator-=(const rettype &m) {*this = *this-m;return *this;} \
00373 rettype &operator*=(const rettype &m) {*this = *this*m;return *this;} \
00374 rettype &operator/=(const rettype &m) {*this = *this/m;return *this;}
00375
00377 #define mcVALUE_DEFINE_ALLOPERATORS(x, structname, y) \
00378 mcVALUE_DEFINE_UNARY_OPERATORS(x, structname, y); \
00379 \
00380 mcVALUE_DEFINE_ARITHMETIC_OPERATORS(x, const x &, const x &, y, a.cMP(), b.cMP()); \
00381 mcVALUE_DEFINE_ARITHMETIC_OPERATORS(x, const x &, long, y, a.cMP(), x(b).cMP()); \
00382 mcVALUE_DEFINE_ARITHMETIC_OPERATORS(x, const x &, int, y, a.cMP(), x(b).cMP()); \
00383 mcVALUE_DEFINE_ARITHMETIC_OPERATORS(x, long, const x &, y, x(a).cMP(), b.cMP()); \
00384 mcVALUE_DEFINE_ARITHMETIC_OPERATORS(x, int, const x &, y, x(a).cMP(), b.cMP()); \
00385 \
00386 mcVALUE_DEFINE_FLAGSCOMPARISON_OPERATORS(const x &, __g##y##_cmp, m.cMP()); \
00387 mcVALUE_DEFINE_NOFLAGSCOMPARISON_OPERATORS(long, __g##y##_cmp_si, m); \
00388 mcVALUE_DEFINE_NOFLAGSCOMPARISON_OPERATORS(int, __g##y##_cmp_si, (long)m); \
00389 mcVALUE_DEFINE_MISCELLANEOUS(x, y)
00390
00391 #define mcVALUE_DEFINE_DOUBLEOPERATORS(x, structname, y) \
00392 mcVALUE_DEFINE_ARITHMETIC_OPERATORS(x, const x &, double, y, a.cMP(), x(b).cMP()); \
00393 mcVALUE_DEFINE_ARITHMETIC_OPERATORS(x, double, const x &, y, x(a).cMP(), b.cMP()); \
00394 mcVALUE_DEFINE_NOFLAGSCOMPARISON_OPERATORS(double, __g##y##_cmp_d, m)
00395
00396
00398 #define mcVALUE_DEFINE_COW(x, y) \
00399 protected: \
00400 mcVALUE_DEFINE_INTERNALS(x, y); \
00401 mcVALUE_DEFINE_REFCOUNT(x, y); \
00402 public: \
00403 mcVALUE_DEFINE_INTERNAL_GETTERS(x)
00404
00406 #define mcVALUE_DEFINE_CONSTRUCTORS(x, y) \
00407 x() { InternalInit(); } \
00408 x(long n) { InternalInit(); SetLong(n); } \
00409 x(int n) { InternalInit(); SetLong(n); } \
00410 x(const wxString &str) { InternalInit(); SetStr(str); } \
00411 x(y *m) { mp=m; Ref(mp); } \
00412 x(const x &m) { mp=m.mp; Ref(mp); } \
00413 virtual ~x() { Unref(); }
00414
00416
00417
00418
00419
00420
00423 class mcValue
00424 {
00425 public:
00426
00429 static int m_nMaxValueSharing;
00430
00431 public:
00432 mcValue() {}
00433 virtual ~mcValue() {}
00434
00435
00438 static void Init();
00439
00443 static void Cleanup();
00444
00445
00446 public:
00447
00448 virtual void SetInt(int n) { SetLong(n); }
00449 virtual void SetLong(long n) = 0;
00450 virtual void SetStr(const wxString &str, int base = 10) = 0;
00451
00452 virtual long GetLong() const = 0;
00453 virtual int GetInt() const { return (int)GetLong(); }
00454
00455 operator int() const { return GetInt(); }
00456 operator long() const { return GetLong(); }
00457 #ifndef __BORLANDC__
00458 operator unsigned long() { return (unsigned long)GetLong(); }
00459 #endif
00460
00474 virtual wxString GetStr() const = 0;
00475
00476 public:
00477
00480 bool isValid() const { return !isNAN() & math_isFinite(); }
00481
00483 bool isNAN() const { return (GetFlags() & mcVALUE_NAN_FLAG) != 0; }
00484
00486 bool math_isFinite() const { return !isPosInf() & !isNegInf(); }
00487
00488 bool isPosInf() const { return (GetFlags() & mcVALUE_POSINF_FLAG) != 0; }
00489 bool isNegInf() const { return (GetFlags() & mcVALUE_NEGINF_FLAG) != 0; }
00490
00493 virtual bool isInteger() const = 0;
00494
00497 virtual int GetFlags() const = 0;
00498
00501 virtual void SetFlags(int n) = 0;
00502
00505 void math_AddFlag(int n) { SetFlags(n | GetFlags()); }
00506 };
00507
00509 class mcIntegerValue : public mcValue
00510 {
00511 mcVALUE_DEFINE_COW(mcMPZ, mpz);
00512
00513 public:
00514
00515 static mcIntegerValue *pOne;
00516 static mcIntegerValue *pZero;
00517 static mcIntegerValue *pNAN;
00518 static mcIntegerValue *pPosInf;
00519 static mcIntegerValue *pNegInf;
00520
00521 public:
00522 mcVALUE_DEFINE_CONSTRUCTORS(mcIntegerValue, mcMPZ);
00523 mcIntegerValue(const mcRationalValue &m);
00524 mcIntegerValue(const mcRealValue &m);
00525
00526
00527 public:
00528
00529 mcVALUE_DEFINE_GETSET(mcIntegerValue, mpz);
00530 mcVALUE_DEFINE_ALLOPERATORS(mcIntegerValue, mcMPZ, mpz);
00531
00533 mcIntegerValue abs() const
00534 { mcIntegerValue ret; mpz_abs(ret.MP(), cMP()); return ret; }
00535
00537 mcIntegerValue pow(unsigned long int exp) const
00538 { mcIntegerValue ret; mpz_pow_ui(ret.MP(), cMP(), exp); return ret; }
00539
00540 mcIntegerValue GetMax(const mcIntegerValue &n) const
00541 { if (*this > n) return *this; else return n; }
00542
00543 mcIntegerValue GetMin(const mcIntegerValue &n) const
00544 { if (*this < n) return *this; else return n; }
00545
00547 wxString GetStr() const;
00548
00550 bool isInteger() const { return TRUE; }
00551
00553 bool isPrimeTo(const mcIntegerValue &n) const { return (GCD(n) == 1); }
00554
00555 static mcIntegerValue GetComb(const mcIntegerValue &n1, const mcIntegerValue &n2)
00556 { mcIntegerValue rop; mpz_bin_ui(rop.MP(), n1.cMP(), n2.GetLong()); return rop; }
00557
00566 mcIntegerValue GCD(const mcIntegerValue &n) const
00567 { mcIntegerValue ret; mpz_gcd(ret.MP(), cMP(), n.cMP()); return ret; }
00568
00575 mcIntegerValue LCM(const mcIntegerValue &n) const
00576 { mcIntegerValue ret; mpz_lcm(ret.MP(), cMP(), n.cMP()); return ret; }
00577 };
00578
00579
00583 class mcRationalValue : public mcValue
00584 {
00585 mcVALUE_DEFINE_COW(mcMPQ, mpq);
00586
00587 public:
00588 mcVALUE_DEFINE_CONSTRUCTORS(mcRationalValue, mcMPQ);
00589 mcRationalValue(const mcIntegerValue &m);
00590 mcRationalValue(const mcRealValue &m);
00591 mcRationalValue(const mcIntegerValue &num, const mcIntegerValue &den);
00592
00593
00594 mcIntegerValue GetDen() const
00595 { mcIntegerValue ret; mpq_get_den(ret.MP(), cMP()); return ret; }
00596 mcIntegerValue GetNum() const
00597 { mcIntegerValue ret; mpq_get_num(ret.MP(), cMP()); return ret; }
00598
00601 void Canonicalize()
00602 { mpq_canonicalize(MP()); }
00603
00604 public:
00605
00606 mcVALUE_DEFINE_SETGET_FLAGS();
00607 mcVALUE_DEFINE_MISCELLANEOUS(mcRationalValue, mpq);
00608
00609
00610 void SetLong(long n) { mpq_set_si(MP(), n, 1); }
00611 void SetDouble(double n) { mpq_set_d(MP(), n); }
00612 void SetStr(const wxString &str, int base = 10)
00613 { mpq_set_str(MP(), WX2GMP(str), base); }
00614
00615 double GetDouble() const { return mpq_get_d(cMP()); }
00616 long GetLong() const { return (long)GetDouble(); }
00617
00619 wxString GetStr() const;
00620
00622 bool isInteger() const { return GetDen() == 1; }
00623
00625 mcRationalValue abs() const
00626 { mcRationalValue ret; mpq_abs(ret.MP(), cMP()); return ret; }
00627
00634 mcRationalValue GetFractionalPart() const;
00635
00637 int GetFractionalDigitCount(int digits = mcVALUE_DEFAULTPRECISION) const;
00638
00642 mcIntegerValue GetIntegerPart() const;
00643
00647 mcIntegerValue MakeInteger(int digits = mcVALUE_DEFAULTPRECISION) const;
00648 };
00649
00650
00653 class mcRealValue : public mcValue
00654 {
00655 mcVALUE_DEFINE_COW(mcMPF, mpf);
00656
00657 protected:
00658
00660 wxString GetBaseStr(int *p, int digits, int *n) const;
00661
00662 public:
00663
00664 static mcRealValue *pOne;
00665 static mcRealValue *pZero;
00666 static mcRealValue *pNAN;
00667 static mcRealValue *pPosInf;
00668 static mcRealValue *pNegInf;
00669
00670 public:
00671 mcVALUE_DEFINE_CONSTRUCTORS(mcRealValue, mcMPF);
00672 mcRealValue(double f) { InternalInit(); SetDouble(f); }
00673 mcRealValue(const mcRationalValue &m) { InternalInit(m.GetFlags()); mpf_set_q(MP(), m.cMP()); }
00674 mcRealValue(const mcIntegerValue &m) { InternalInit(m.GetFlags()); mpf_set_z(MP(), m.cMP()); }
00675
00676
00677 public:
00678
00679 mcRealValue pow(unsigned long n) const
00680 { mcRealValue ret; mpf_pow_ui(ret.MP(), cMP(), n); return ret; }
00681 mcRealValue pow(int n) const
00682 { mcRealValue ret; mpf_pow_ui(ret.MP(), cMP(), n); return ret; }
00683 mcRealValue pow(double n) const
00684 { mcRealValue ret; ret.SetDouble(::pow(GetDouble(), n)); return ret; }
00685 mcRealValue pow(const mcRealValue &n) const
00686 { return this->pow(n.GetDouble()); }
00687 mcRealValue root(const mcRealValue &n)
00688 { mcRealValue exp=1.0 / n; return this->pow(exp); }
00689
00690 mcRealValue abs() const { mcRealValue ret; mpf_abs(ret.MP(), cMP()); return ret; }
00691 mcRealValue floor() const { mcRealValue ret; mpf_floor(ret.MP(), cMP()); return ret; }
00692 mcRealValue ceil() const { mcRealValue ret; mpf_ceil(ret.MP(), cMP()); return ret; }
00693 mcRealValue trunc() const { mcRealValue ret; mpf_trunc(ret.MP(), cMP()); return ret; }
00694
00697 bool isInteger() const { return mpf_integer_p(cMP()) != 0; }
00698
00700 mcRealValue GetReciprocal() const { return 1.0 / (*this); }
00701
00702 public:
00703
00704 mcVALUE_DEFINE_ALLOPERATORS(mcRealValue, mcMPF, mpf);
00705 mcVALUE_DEFINE_DOUBLEOPERATORS(mcRealValue, mcMPF, mpf);
00706 mcVALUE_DEFINE_GETSET(mcRealValue, mpf);
00707 mcVALUE_DEFINE_FLAGSCOMPARISON_OPERATORS(mcIntegerValue, mpf_cmp_si, m.GetLong());
00708
00710 wxString GetStr() const { return GetStr(mcVALUE_DEFAULTPRECISION); }
00711 wxString GetStr(int digits) const;
00712
00723 virtual wxString GetExtStr(int digits = mcVALUE_DEFAULTPRECISION) const;
00724
00728 virtual wxString GetSmartStr(int threshold = mcVALUE_SMARTSTR_THRESHOLD,
00729 int digits = mcVALUE_DEFAULTPRECISION) const;
00730
00731
00732 double GetDouble() const { return mpf_get_d(cMP()); }
00733 void SetDouble(double n) { mpf_set_d(MP(), n); }
00734
00735 mcRealValue &operator=(double d) { SetDouble(d); return *this;} \
00736 operator double() const { return GetDouble(); }
00737
00738 public:
00739
00740
00741
00742
00743
00744 int GetNumOfDigits(int digits = mcVALUE_DEFAULTPRECISION) const;
00745 mcRealValue GetFromDigitRange(int begin, int end = -1, int digits = mcVALUE_DEFAULTPRECISION) const;
00746
00747
00748
00749
00750
00751
00752 mcRealValue DeleteDigit(int pos, int digits = mcVALUE_DEFAULTPRECISION) const;
00753 mcRealValue InsertDigit(wxChar digit, int pos, int digits = mcVALUE_DEFAULTPRECISION) const;
00754 mcRealValue AppendDigit(wxChar digit, int digits = mcVALUE_DEFAULTPRECISION) const
00755 { return InsertDigit(digit, -1, digits); }
00756 };
00757
00758
00760 class mcComplexValue : public mcValue
00761 {
00762
00763
00764 };
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781 #endif // VALUE_H