Planeshift
|
00001 #ifndef ONCE_FP_MPFR_FLOAT_ 00002 #define ONCE_FP_MPFR_FLOAT_ 00003 00004 #include <iostream> 00005 00006 class MpfrFloat 00007 { 00008 public: 00009 /* A default of 256 bits will be used unless changed with this function. 00010 Note that all existing and cached GMP objects will be resized to the 00011 specified precision (which can be a somewhat heavy operation). 00012 */ 00013 static void setDefaultMantissaBits(unsigned long bits); 00014 00015 static unsigned long getCurrentDefaultMantissaBits(); 00016 00017 /* The default constructor initializes the object to the value 0. 00018 It's efficient to instantiate such zero-initialized objects because 00019 all of them will share the same mpfr data. (Also any object initialized 00020 with or assigned the explicit value of zero will also share that one 00021 mpfr data.) Thus multiple zero-initialized MpfrFloat instances won't 00022 consume significant amounts of memory (until they are modified to 00023 contain some other value, of course). 00024 00025 Important caveat: 00026 ---------------- 00027 Note that initializing an MpfrFloat object with, for example, 0.1 will 00028 suffer from accuracy problems (at least if the MpfrFloat object has 00029 more mantissa bits than a double). The C++ double value 0.1 has only 00030 53 mantissa bits, while the MpfrFloat object usually has more. If the 00031 MpfrFloat object is initialized with a double, only that many bits of 00032 accuracy will end up in the value of the MpfrFloat object. This can 00033 create significant rounding/accuracy problems in some cases. 00034 If you need to initialize the MpfrObject with some value (which cannot 00035 be represented accurately by base-2 floating point numbers, eg. 0.1) 00036 at full mantissa precision, you have to use parseValue("0.1") instead, 00037 rather than relying on the constructor taking a double type value. 00038 */ 00039 MpfrFloat(); 00040 MpfrFloat(double value); 00041 MpfrFloat(long double value); 00042 MpfrFloat(long value); 00043 MpfrFloat(int value); 00044 MpfrFloat(const char* value, char** endptr); 00045 00046 ~MpfrFloat(); 00047 00048 MpfrFloat(const MpfrFloat&); 00049 00050 MpfrFloat& operator=(const MpfrFloat&); 00051 MpfrFloat& operator=(double value); 00052 MpfrFloat& operator=(long double value); 00053 MpfrFloat& operator=(long value); 00054 MpfrFloat& operator=(int value); 00055 //MpfrFloat& operator=(const char* value); 00056 00057 void parseValue(const char* value); 00058 void parseValue(const char* value, char** endptr); 00059 00060 00061 /* This function can be used to retrieve the raw mpfr_t data structure 00062 used by this object. (The template trick is used to avoid a dependency 00063 of this header file with <mpfr.h>.) 00064 In other words, it can be called like: 00065 00066 mpfr_t raw_mpfr_data; 00067 floatValue.get_raw_mpfr_data(raw_mpfr_data); 00068 00069 Note that the returned mpfr_t should be considered as read-only and 00070 not be modified from the outside because it may be shared among 00071 several objects. If the calling code needs to modify the data, it 00072 should copy it for itself first with the appropriate MPFR library 00073 functions. 00074 */ 00075 template<typename Mpfr_t> 00076 void get_raw_mpfr_data(Mpfr_t& dest_mpfr_t); 00077 00078 00079 /* Note that the returned char* points to an internal (shared) buffer 00080 which will be valid until the next time this function is called 00081 (by any object). 00082 */ 00083 const char* getAsString(unsigned precision) const; 00084 00085 bool isInteger() const; 00086 long toInt() const; 00087 double toDouble() const; 00088 00089 MpfrFloat& operator+=(const MpfrFloat&); 00090 MpfrFloat& operator+=(double); 00091 MpfrFloat& operator-=(const MpfrFloat&); 00092 MpfrFloat& operator-=(double); 00093 MpfrFloat& operator*=(const MpfrFloat&); 00094 MpfrFloat& operator*=(double); 00095 MpfrFloat& operator/=(const MpfrFloat&); 00096 MpfrFloat& operator/=(double); 00097 MpfrFloat& operator%=(const MpfrFloat&); 00098 00099 void negate(); 00100 void abs(); 00101 00102 MpfrFloat operator+(const MpfrFloat&) const; 00103 MpfrFloat operator+(double) const; 00104 MpfrFloat operator-(const MpfrFloat&) const; 00105 MpfrFloat operator-(double) const; 00106 MpfrFloat operator*(const MpfrFloat&) const; 00107 MpfrFloat operator*(double) const; 00108 MpfrFloat operator/(const MpfrFloat&) const; 00109 MpfrFloat operator/(double) const; 00110 MpfrFloat operator%(const MpfrFloat&) const; 00111 00112 MpfrFloat operator-() const; 00113 00114 bool operator<(const MpfrFloat&) const; 00115 bool operator<(double) const; 00116 bool operator<=(const MpfrFloat&) const; 00117 bool operator<=(double) const; 00118 bool operator>(const MpfrFloat&) const; 00119 bool operator>(double) const; 00120 bool operator>=(const MpfrFloat&) const; 00121 bool operator>=(double) const; 00122 bool operator==(const MpfrFloat&) const; 00123 bool operator==(double) const; 00124 bool operator!=(const MpfrFloat&) const; 00125 bool operator!=(double) const; 00126 00127 static MpfrFloat log(const MpfrFloat&); 00128 static MpfrFloat log2(const MpfrFloat&); 00129 static MpfrFloat log10(const MpfrFloat&); 00130 static MpfrFloat exp(const MpfrFloat&); 00131 static MpfrFloat exp2(const MpfrFloat&); 00132 static MpfrFloat exp10(const MpfrFloat&); 00133 static MpfrFloat cos(const MpfrFloat&); 00134 static MpfrFloat sin(const MpfrFloat&); 00135 static MpfrFloat tan(const MpfrFloat&); 00136 static MpfrFloat sec(const MpfrFloat&); 00137 static MpfrFloat csc(const MpfrFloat&); 00138 static MpfrFloat cot(const MpfrFloat&); 00139 static void sincos(const MpfrFloat&, MpfrFloat& sin, MpfrFloat& cos); 00140 static MpfrFloat acos(const MpfrFloat&); 00141 static MpfrFloat asin(const MpfrFloat&); 00142 static MpfrFloat atan(const MpfrFloat&); 00143 static MpfrFloat atan2(const MpfrFloat&, const MpfrFloat&); 00144 static MpfrFloat hypot(const MpfrFloat&, const MpfrFloat&); 00145 static MpfrFloat cosh(const MpfrFloat&); 00146 static MpfrFloat sinh(const MpfrFloat&); 00147 static MpfrFloat tanh(const MpfrFloat&); 00148 static MpfrFloat acosh(const MpfrFloat&); 00149 static MpfrFloat asinh(const MpfrFloat&); 00150 static MpfrFloat atanh(const MpfrFloat&); 00151 static MpfrFloat sqrt(const MpfrFloat&); 00152 static MpfrFloat cbrt(const MpfrFloat&); 00153 static MpfrFloat root(const MpfrFloat&, unsigned long root); 00154 static MpfrFloat pow(const MpfrFloat&, const MpfrFloat&); 00155 static MpfrFloat pow(const MpfrFloat&, long exponent); 00156 static MpfrFloat abs(const MpfrFloat&); 00157 static MpfrFloat dim(const MpfrFloat&, const MpfrFloat&); 00158 static MpfrFloat round(const MpfrFloat&); 00159 static MpfrFloat ceil(const MpfrFloat&); 00160 static MpfrFloat floor(const MpfrFloat&); 00161 static MpfrFloat trunc(const MpfrFloat&); 00162 00163 static MpfrFloat parseString(const char* str, char** endptr); 00164 00165 // These values are cached (and recalculated every time the mantissa bits 00166 // change), so it's efficient to call these repeatedly: 00167 static MpfrFloat const_pi(); 00168 static MpfrFloat const_e(); 00169 static MpfrFloat const_log2(); 00170 static MpfrFloat someEpsilon(); 00171 00172 00173 private: 00174 struct MpfrFloatData; 00175 class MpfrFloatDataContainer; 00176 00177 MpfrFloatData* mData; 00178 00179 enum DummyType { kNoInitialization }; 00180 MpfrFloat(DummyType); 00181 MpfrFloat(MpfrFloatData*); 00182 00183 void copyIfShared(); 00184 static MpfrFloatDataContainer& mpfrFloatDataContainer(); 00185 00186 friend MpfrFloat operator+(double lhs, const MpfrFloat& rhs); 00187 friend MpfrFloat operator-(double lhs, const MpfrFloat& rhs); 00188 }; 00189 00190 MpfrFloat operator+(double lhs, const MpfrFloat& rhs); 00191 MpfrFloat operator-(double lhs, const MpfrFloat& rhs); 00192 MpfrFloat operator*(double lhs, const MpfrFloat& rhs); 00193 MpfrFloat operator/(double lhs, const MpfrFloat& rhs); 00194 MpfrFloat operator%(double lhs, const MpfrFloat& rhs); 00195 00196 inline bool operator<(double lhs, const MpfrFloat& rhs) { return rhs > lhs; } 00197 inline bool operator<=(double lhs, const MpfrFloat& rhs) { return rhs >= lhs; } 00198 inline bool operator>(double lhs, const MpfrFloat& rhs) { return rhs < lhs; } 00199 inline bool operator>=(double lhs, const MpfrFloat& rhs) { return rhs <= lhs; } 00200 inline bool operator==(double lhs, const MpfrFloat& rhs) { return rhs == lhs; } 00201 inline bool operator!=(double lhs, const MpfrFloat& rhs) { return rhs != lhs; } 00202 00203 // This function takes into account the value of os.precision() 00204 std::ostream& operator<<(std::ostream& os, const MpfrFloat& value); 00205 00206 #endif