Planeshift

MpfrFloat.h

Go to the documentation of this file.
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