Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

Value.h

Go to the documentation of this file.
00001 
00002 // MathCore = a WYSIWYG equation editor + a powerful math engine     //
00003 // Copyright (C) 2003 by Francesco Montorsi                          //
00004 //                                                                   //
00005 // This library is free software; you can redistribute it and/or     //
00006 // modify it under the terms of the GNU Lesser General Public        //
00007 // License as published by the Free Software Foundation; either      //
00008 // version 2.1 of the License, or (at your option) any later         //
00009 // version.                                                          //
00010 //                                                                   //
00011 // This library is distributed in the hope that it will be useful,   //
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of    //
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the      //
00014 // GNU Lesser General Public License for more details.               //
00015 //                                                                   //
00016 // You should have received a copy of the GNU Lesser General Public  //
00017 // License along with this program; if not, write to the Free        //
00018 // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,   //
00019 // MA 02111-1307, USA.                                               //
00020 //                                                                   //
00021 // For any comment, suggestion or feature request, please contact    //
00022 // the administrator of the project at frm@users.sourceforge.net     //
00023 //                                                                   //
00030 
00031 
00032 
00033 #ifndef VALUE_H
00034 #define VALUE_H
00035 
00036 // optimization for GCC compiler
00037 #ifdef __GNUG__
00038 #pragma interface "Value.h"
00039 #endif
00040 
00041 // required includes
00042 #include "mc/Setup.h"
00043 #include <math.h>   // In any case we'll need the standard pow() since GMP
00044                             // does not have a mpf_pow(mpf_t rop, mpf_t base, mpf_t exp)
00045 
00046 #ifdef mcUSE_GMP
00047 
00048  #include <gmp.h>  // The main include of the GNU Multiple Precision library
00049 
00050 #else
00051 
00052  // DUMMY GMP-LIKE INTERFACE (only for debugging)
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  // MPF functions
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 = new __mpf_struct;*/ op.val = 0; }
00073  static void mpf_clear(mpf_t op) { /*delete 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  // MPZ functions
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  // MPQ functions
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 // these will be defined later
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);  /* DO NOT USE MP() !! */    \
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   /* make a private instance copying the shared object */   \
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() {}  // cannot build anything since everything is declared in derived classes.
00433  virtual ~mcValue() {}
00434 
00435 
00438  static void Init();
00439 
00443  static void Cleanup();
00444 
00445 
00446 public:  // standard conversions
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:  // miscellaneous functions
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:  // static
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  //mcVALUE_DEFINE_ALLOPERATORS(mcRationalValue, mcMPQ, mpq)
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:  // static
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:  // math.h-like functions
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:  // operators
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:   // digit-manipulation functions
00739 
00740  // -------------------
00741  // Digit getters
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  // Digit manipulation
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 class mcNaturalValue : public mcValue
00772 {
00773 };*/
00774 
00775 /*
00776 inline mcValue pow(const mcValue &x,const mcValue &y)  {return x.pow(y.GetLong());}
00777 inline mcValue gcd(const mcValue &u,const mcValue &v)  {return u.GCD(v);}
00778 inline mcValue lcm(const mcValue &u,const mcValue &v)  {return u.LCM(v);}
00779 */
00780 
00781 #endif  // VALUE_H


Documentation generated with Doxygen on Sun Feb 6 17:10:49 2005
Visit MathStudio home page for more info

[ Top ]