mpreal.h
Go to the documentation of this file.
00001 /*
00002     MPFR C++: Multi-precision floating point number class for C++. 
00003     Based on MPFR library:    http://mpfr.org
00004 
00005     Project homepage:    http://www.holoborodko.com/pavel/mpfr
00006     Contact e-mail:      pavel@holoborodko.com
00007 
00008     Copyright (c) 2008-2014 Pavel Holoborodko
00009 
00010     Contributors:
00011     Dmitriy Gubanov, Konstantin Holoborodko, Brian Gladman, 
00012     Helmut Jarausch, Fokko Beekhof, Ulrich Mutze, Heinz van Saanen, 
00013     Pere Constans, Peter van Hoof, Gael Guennebaud, Tsai Chia Cheng, 
00014     Alexei Zubanov, Jauhien Piatlicki, Victor Berger, John Westwood,
00015     Petr Aleksandrov, Orion Poplawski, Charles Karney.
00016 
00017     Licensing:
00018     (A) MPFR C++ is under GNU General Public License ("GPL").
00019     
00020     (B) Non-free licenses may also be purchased from the author, for users who 
00021         do not want their programs protected by the GPL.
00022 
00023         The non-free licenses are for users that wish to use MPFR C++ in 
00024         their products but are unwilling to release their software 
00025         under the GPL (which would require them to release source code 
00026         and allow free redistribution).
00027 
00028         Such users can purchase an unlimited-use license from the author.
00029         Contact us for more details.
00030     
00031     GNU General Public License ("GPL") copyright permissions statement:
00032     **************************************************************************
00033     This program is free software: you can redistribute it and/or modify
00034     it under the terms of the GNU General Public License as published by
00035     the Free Software Foundation, either version 3 of the License, or
00036     (at your option) any later version.
00037 
00038     This program is distributed in the hope that it will be useful,
00039     but WITHOUT ANY WARRANTY; without even the implied warranty of
00040     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00041     GNU General Public License for more details.
00042 
00043     You should have received a copy of the GNU General Public License
00044     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00045 */
00046 
00047 #ifndef __MPREAL_H__
00048 #define __MPREAL_H__
00049 
00050 #include <string>
00051 #include <iostream>
00052 #include <sstream>
00053 #include <stdexcept>
00054 #include <cfloat>
00055 #include <cmath>
00056 #include <cstring>
00057 #include <limits>
00058 
00059 // Options
00060 // FIXME HAVE_INT64_SUPPORT leads to clashes with long int and int64_t on some systems.
00061 //#define MPREAL_HAVE_INT64_SUPPORT               // Enable int64_t support if possible. Available only for MSVC 2010 & GCC.
00062 #define MPREAL_HAVE_MSVC_DEBUGVIEW              // Enable Debugger Visualizer for "Debug" builds in MSVC.
00063 #define MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS  // Enable extended std::numeric_limits<mpfr::mpreal> specialization.
00064                                                 // Meaning that "digits", "round_style" and similar members are defined as functions, not constants.
00065                                                 // See std::numeric_limits<mpfr::mpreal> at the end of the file for more information.
00066 
00067 // Library version
00068 #define MPREAL_VERSION_MAJOR 3
00069 #define MPREAL_VERSION_MINOR 5
00070 #define MPREAL_VERSION_PATCHLEVEL 9
00071 #define MPREAL_VERSION_STRING "3.5.9"
00072 
00073 // Detect compiler using signatures from http://predef.sourceforge.net/
00074 #if defined(__GNUC__) && defined(__INTEL_COMPILER)
00075     #define IsInf(x) isinf(x)                   // Intel ICC compiler on Linux 
00076 
00077 #elif defined(_MSC_VER)                         // Microsoft Visual C++ 
00078     #define IsInf(x) (!_finite(x))                           
00079 
00080 #else
00081     #define IsInf(x) std::isinf(x)              // GNU C/C++ (and/or other compilers), just hope for C99 conformance
00082 #endif
00083 
00084 // A Clang feature extension to determine compiler features.
00085 #ifndef __has_feature
00086     #define __has_feature(x) 0
00087 #endif
00088 
00089 // Detect support for r-value references (move semantic). Borrowed from Eigen.
00090 #if (__has_feature(cxx_rvalue_references) || \
00091        defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \
00092       (defined(_MSC_VER) && _MSC_VER >= 1600))
00093 
00094     #define MPREAL_HAVE_MOVE_SUPPORT
00095 
00096     // Use fields in mpfr_t structure to check if it was initialized / set dummy initialization 
00097     #define mpfr_is_initialized(x)      (0 != (x)->_mpfr_d)
00098     #define mpfr_set_uninitialized(x)   ((x)->_mpfr_d = 0 )
00099 #endif
00100 
00101 // Detect support for explicit converters. 
00102 #if (__has_feature(cxx_explicit_conversions) || \
00103        defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \
00104       (defined(_MSC_VER) && _MSC_VER >= 1800))
00105 
00106     #define MPREAL_HAVE_EXPLICIT_CONVERTERS
00107 #endif
00108 
00109 // Detect available 64-bit capabilities
00110 #if defined(MPREAL_HAVE_INT64_SUPPORT)
00111     
00112     #define MPFR_USE_INTMAX_T                   // Should be defined before mpfr.h
00113 
00114     #if defined(_MSC_VER)                       // MSVC + Windows
00115         #if (_MSC_VER >= 1600)                    
00116             #include <stdint.h>                 // <stdint.h> is available only in msvc2010!
00117 
00118         #else                                   // MPFR relies on intmax_t which is available only in msvc2010
00119             #undef MPREAL_HAVE_INT64_SUPPORT    // Besides, MPFR & MPIR have to be compiled with msvc2010
00120             #undef MPFR_USE_INTMAX_T            // Since we cannot detect this, disable x64 by default
00121                                                 // Someone should change this manually if needed.
00122         #endif
00123 
00124     #elif defined (__GNUC__) && defined(__linux__)
00125         #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) || defined (__PPC64__)
00126             #undef MPREAL_HAVE_INT64_SUPPORT    // Remove all shaman dances for x64 builds since
00127             #undef MPFR_USE_INTMAX_T            // GCC already supports x64 as of "long int" is 64-bit integer, nothing left to do
00128         #else
00129             #include <stdint.h>                 // use int64_t, uint64_t otherwise
00130         #endif
00131 
00132     #else
00133         #include <stdint.h>                     // rely on int64_t, uint64_t in all other cases, Mac OSX, etc.
00134     #endif
00135 
00136 #endif 
00137 
00138 #if defined(MPREAL_HAVE_MSVC_DEBUGVIEW) && defined(_MSC_VER) && defined(_DEBUG)
00139     #define MPREAL_MSVC_DEBUGVIEW_CODE     DebugView = toString();
00140     #define MPREAL_MSVC_DEBUGVIEW_DATA     std::string DebugView;
00141 #else
00142     #define MPREAL_MSVC_DEBUGVIEW_CODE 
00143     #define MPREAL_MSVC_DEBUGVIEW_DATA 
00144 #endif
00145 
00146 #include <mpfr.h>
00147 
00148 #if (MPFR_VERSION < MPFR_VERSION_NUM(3,0,0))
00149     #include <cstdlib>                          // Needed for random()
00150 #endif
00151 
00152 // Less important options
00153 #define MPREAL_DOUBLE_BITS_OVERFLOW -1          // Triggers overflow exception during conversion to double if mpreal 
00154                                                 // cannot fit in MPREAL_DOUBLE_BITS_OVERFLOW bits
00155                                                 // = -1 disables overflow checks (default)
00156 #if defined(__GNUC__)
00157   #define MPREAL_PERMISSIVE_EXPR __extension__
00158 #else
00159   #define MPREAL_PERMISSIVE_EXPR
00160 #endif
00161 
00162 namespace mpfr {
00163 
00164 class mpreal {
00165 private:
00166     mpfr_t mp;
00167     
00168 public:
00169     
00170     // Get default rounding mode & precision
00171     inline static mp_rnd_t   get_default_rnd()    {    return (mp_rnd_t)(mpfr_get_default_rounding_mode());       }
00172     inline static mp_prec_t  get_default_prec()   {    return mpfr_get_default_prec();                            }
00173 
00174     // Constructors && type conversions
00175     mpreal();
00176     mpreal(const mpreal& u);
00177     mpreal(const mpf_t u);    
00178     mpreal(const mpz_t u,             mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());    
00179     mpreal(const mpq_t u,             mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());    
00180     mpreal(const double u,            mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
00181     mpreal(const long double u,       mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
00182     mpreal(const unsigned long int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
00183     mpreal(const unsigned int u,      mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
00184     mpreal(const long int u,          mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
00185     mpreal(const int u,               mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
00186     
00187     // Construct mpreal from mpfr_t structure.
00188     // shared = true allows to avoid deep copy, so that mpreal and 'u' share the same data & pointers.    
00189     mpreal(const mpfr_t  u, bool shared = false);   
00190 
00191 #if defined (MPREAL_HAVE_INT64_SUPPORT)
00192     mpreal(const uint64_t u,          mp_prec_t prec = mpreal::get_default_prec(),  mp_rnd_t mode = mpreal::get_default_rnd());
00193     mpreal(const int64_t u,           mp_prec_t prec = mpreal::get_default_prec(),  mp_rnd_t mode = mpreal::get_default_rnd());
00194 #endif
00195 
00196     mpreal(const char* s,             mp_prec_t prec = mpreal::get_default_prec(), int base = 10, mp_rnd_t mode = mpreal::get_default_rnd());
00197     mpreal(const std::string& s,      mp_prec_t prec = mpreal::get_default_prec(), int base = 10, mp_rnd_t mode = mpreal::get_default_rnd());
00198 
00199     ~mpreal();                           
00200 
00201 #ifdef MPREAL_HAVE_MOVE_SUPPORT
00202     mpreal& operator=(mpreal&& v);
00203     mpreal(mpreal&& u);
00204 #endif
00205 
00206     // Operations
00207     // =
00208     // +, -, *, /, ++, --, <<, >> 
00209     // *=, +=, -=, /=,
00210     // <, >, ==, <=, >=
00211 
00212     // =
00213     mpreal& operator=(const mpreal& v);
00214     mpreal& operator=(const mpf_t v);
00215     mpreal& operator=(const mpz_t v);
00216     mpreal& operator=(const mpq_t v);
00217     mpreal& operator=(const long double v);
00218     mpreal& operator=(const double v);        
00219     mpreal& operator=(const unsigned long int v);
00220     mpreal& operator=(const unsigned int v);
00221     mpreal& operator=(const long int v);
00222     mpreal& operator=(const int v);
00223     mpreal& operator=(const char* s);
00224     mpreal& operator=(const std::string& s);
00225 
00226     // +
00227     mpreal& operator+=(const mpreal& v);
00228     mpreal& operator+=(const mpf_t v);
00229     mpreal& operator+=(const mpz_t v);
00230     mpreal& operator+=(const mpq_t v);
00231     mpreal& operator+=(const long double u);
00232     mpreal& operator+=(const double u);
00233     mpreal& operator+=(const unsigned long int u);
00234     mpreal& operator+=(const unsigned int u);
00235     mpreal& operator+=(const long int u);
00236     mpreal& operator+=(const int u);
00237 
00238 #if defined (MPREAL_HAVE_INT64_SUPPORT)
00239     mpreal& operator+=(const int64_t  u);
00240     mpreal& operator+=(const uint64_t u);
00241     mpreal& operator-=(const int64_t  u);
00242     mpreal& operator-=(const uint64_t u);
00243     mpreal& operator*=(const int64_t  u);
00244     mpreal& operator*=(const uint64_t u);
00245     mpreal& operator/=(const int64_t  u);
00246     mpreal& operator/=(const uint64_t u);
00247 #endif 
00248 
00249     const mpreal operator+() const;
00250     mpreal& operator++ ();
00251     const mpreal  operator++ (int); 
00252 
00253     // -
00254     mpreal& operator-=(const mpreal& v);
00255     mpreal& operator-=(const mpz_t v);
00256     mpreal& operator-=(const mpq_t v);
00257     mpreal& operator-=(const long double u);
00258     mpreal& operator-=(const double u);
00259     mpreal& operator-=(const unsigned long int u);
00260     mpreal& operator-=(const unsigned int u);
00261     mpreal& operator-=(const long int u);
00262     mpreal& operator-=(const int u);
00263     const mpreal operator-() const;
00264     friend const mpreal operator-(const unsigned long int b, const mpreal& a);
00265     friend const mpreal operator-(const unsigned int b,      const mpreal& a);
00266     friend const mpreal operator-(const long int b,          const mpreal& a);
00267     friend const mpreal operator-(const int b,               const mpreal& a);
00268     friend const mpreal operator-(const double b,            const mpreal& a);
00269     mpreal& operator-- ();    
00270     const mpreal  operator-- (int);
00271 
00272     // *
00273     mpreal& operator*=(const mpreal& v);
00274     mpreal& operator*=(const mpz_t v);
00275     mpreal& operator*=(const mpq_t v);
00276     mpreal& operator*=(const long double v);
00277     mpreal& operator*=(const double v);
00278     mpreal& operator*=(const unsigned long int v);
00279     mpreal& operator*=(const unsigned int v);
00280     mpreal& operator*=(const long int v);
00281     mpreal& operator*=(const int v);
00282     
00283     // /
00284     mpreal& operator/=(const mpreal& v);
00285     mpreal& operator/=(const mpz_t v);
00286     mpreal& operator/=(const mpq_t v);
00287     mpreal& operator/=(const long double v);
00288     mpreal& operator/=(const double v);
00289     mpreal& operator/=(const unsigned long int v);
00290     mpreal& operator/=(const unsigned int v);
00291     mpreal& operator/=(const long int v);
00292     mpreal& operator/=(const int v);
00293     friend const mpreal operator/(const unsigned long int b, const mpreal& a);
00294     friend const mpreal operator/(const unsigned int b,      const mpreal& a);
00295     friend const mpreal operator/(const long int b,          const mpreal& a);
00296     friend const mpreal operator/(const int b,               const mpreal& a);
00297     friend const mpreal operator/(const double b,            const mpreal& a);
00298 
00299     //<<= Fast Multiplication by 2^u
00300     mpreal& operator<<=(const unsigned long int u);
00301     mpreal& operator<<=(const unsigned int u);
00302     mpreal& operator<<=(const long int u);
00303     mpreal& operator<<=(const int u);
00304 
00305     //>>= Fast Division by 2^u
00306     mpreal& operator>>=(const unsigned long int u);
00307     mpreal& operator>>=(const unsigned int u);
00308     mpreal& operator>>=(const long int u);
00309     mpreal& operator>>=(const int u);
00310 
00311     // Boolean Operators
00312     friend bool operator >  (const mpreal& a, const mpreal& b);
00313     friend bool operator >= (const mpreal& a, const mpreal& b);
00314     friend bool operator <  (const mpreal& a, const mpreal& b);
00315     friend bool operator <= (const mpreal& a, const mpreal& b);
00316     friend bool operator == (const mpreal& a, const mpreal& b);
00317     friend bool operator != (const mpreal& a, const mpreal& b);
00318 
00319     // Optimized specializations for boolean operators
00320     friend bool operator == (const mpreal& a, const unsigned long int b);
00321     friend bool operator == (const mpreal& a, const unsigned int b);
00322     friend bool operator == (const mpreal& a, const long int b);
00323     friend bool operator == (const mpreal& a, const int b);
00324     friend bool operator == (const mpreal& a, const long double b);
00325     friend bool operator == (const mpreal& a, const double b);
00326 
00327     // Type Conversion operators
00328     bool            toBool      (mp_rnd_t mode = GMP_RNDZ)    const;
00329     long            toLong      (mp_rnd_t mode = GMP_RNDZ)    const;
00330     unsigned long   toULong     (mp_rnd_t mode = GMP_RNDZ)    const;
00331     float           toFloat     (mp_rnd_t mode = GMP_RNDN)    const;
00332     double          toDouble    (mp_rnd_t mode = GMP_RNDN)    const;
00333     long double     toLDouble   (mp_rnd_t mode = GMP_RNDN)    const;
00334 
00335 #if defined (MPREAL_HAVE_EXPLICIT_CONVERTERS)
00336     explicit operator bool               () const { return toBool();       }
00337     explicit operator int                () const { return toLong();       }
00338     explicit operator long               () const { return toLong();       }
00339     explicit operator long long          () const { return toLong();       }
00340     explicit operator unsigned           () const { return toULong();      }
00341     explicit operator unsigned long      () const { return toULong();      }
00342     explicit operator unsigned long long () const { return toULong();      }
00343     explicit operator float              () const { return toFloat();      }
00344     explicit operator double             () const { return toDouble();     }
00345     explicit operator long double        () const { return toLDouble();    }
00346 #endif
00347 
00348 #if defined (MPREAL_HAVE_INT64_SUPPORT)
00349     int64_t         toInt64     (mp_rnd_t mode = GMP_RNDZ)    const;
00350     uint64_t        toUInt64    (mp_rnd_t mode = GMP_RNDZ)    const;
00351 
00352     #if defined (MPREAL_HAVE_EXPLICIT_CONVERTERS)
00353     explicit operator int64_t   () const { return toInt64();      }
00354     explicit operator uint64_t  () const { return toUInt64();     }
00355     #endif
00356 #endif
00357 
00358     // Get raw pointers so that mpreal can be directly used in raw mpfr_* functions
00359     ::mpfr_ptr    mpfr_ptr();
00360     ::mpfr_srcptr mpfr_ptr()    const;
00361     ::mpfr_srcptr mpfr_srcptr() const;
00362 
00363     // Convert mpreal to string with n significant digits in base b
00364     // n = -1 -> convert with the maximum available digits
00365     std::string toString(int n = -1, int b = 10, mp_rnd_t mode = mpreal::get_default_rnd()) const;
00366 
00367 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
00368     std::string toString(const std::string& format) const;
00369 #endif
00370 
00371     std::ostream& output(std::ostream& os) const;
00372 
00373     // Math Functions
00374     friend const mpreal sqr (const mpreal& v, mp_rnd_t rnd_mode);
00375     friend const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode);
00376     friend const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode);
00377     friend const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode);
00378     friend const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode);
00379     friend const mpreal pow (const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode);
00380     friend const mpreal pow (const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode);
00381     friend const mpreal pow (const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode);
00382     friend const mpreal pow (const mpreal& a, const long int b, mp_rnd_t rnd_mode);
00383     friend const mpreal pow (const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode);
00384     friend const mpreal pow (const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode);
00385     friend const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode);
00386 
00387     friend const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode);
00388     friend const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode);
00389     friend inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode);
00390     friend inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode);
00391     friend inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode);
00392     friend inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode);
00393     friend int cmpabs(const mpreal& a,const mpreal& b);
00394     
00395     friend const mpreal log  (const mpreal& v, mp_rnd_t rnd_mode);
00396     friend const mpreal log2 (const mpreal& v, mp_rnd_t rnd_mode);
00397     friend const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode);
00398     friend const mpreal exp  (const mpreal& v, mp_rnd_t rnd_mode); 
00399     friend const mpreal exp2 (const mpreal& v, mp_rnd_t rnd_mode);
00400     friend const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode);
00401     friend const mpreal log1p(const mpreal& v, mp_rnd_t rnd_mode);
00402     friend const mpreal expm1(const mpreal& v, mp_rnd_t rnd_mode);
00403 
00404     friend const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode);
00405     friend const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode);
00406     friend const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode);
00407     friend const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode);
00408     friend const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode);
00409     friend const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode);
00410     friend int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode);
00411 
00412     friend const mpreal acos  (const mpreal& v, mp_rnd_t rnd_mode);
00413     friend const mpreal asin  (const mpreal& v, mp_rnd_t rnd_mode);
00414     friend const mpreal atan  (const mpreal& v, mp_rnd_t rnd_mode);
00415     friend const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode);
00416     friend const mpreal acot  (const mpreal& v, mp_rnd_t rnd_mode);
00417     friend const mpreal asec  (const mpreal& v, mp_rnd_t rnd_mode);
00418     friend const mpreal acsc  (const mpreal& v, mp_rnd_t rnd_mode);
00419 
00420     friend const mpreal cosh  (const mpreal& v, mp_rnd_t rnd_mode);
00421     friend const mpreal sinh  (const mpreal& v, mp_rnd_t rnd_mode);
00422     friend const mpreal tanh  (const mpreal& v, mp_rnd_t rnd_mode);
00423     friend const mpreal sech  (const mpreal& v, mp_rnd_t rnd_mode);
00424     friend const mpreal csch  (const mpreal& v, mp_rnd_t rnd_mode);
00425     friend const mpreal coth  (const mpreal& v, mp_rnd_t rnd_mode);
00426     friend const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode);
00427     friend const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode);
00428     friend const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode);
00429     friend const mpreal acoth (const mpreal& v, mp_rnd_t rnd_mode);
00430     friend const mpreal asech (const mpreal& v, mp_rnd_t rnd_mode);
00431     friend const mpreal acsch (const mpreal& v, mp_rnd_t rnd_mode);
00432 
00433     friend const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
00434 
00435     friend const mpreal fac_ui (unsigned long int v,  mp_prec_t prec, mp_rnd_t rnd_mode);
00436     friend const mpreal eint   (const mpreal& v, mp_rnd_t rnd_mode);
00437 
00438     friend const mpreal gamma    (const mpreal& v, mp_rnd_t rnd_mode);
00439     friend const mpreal lngamma  (const mpreal& v, mp_rnd_t rnd_mode);
00440     friend const mpreal lgamma   (const mpreal& v, int *signp, mp_rnd_t rnd_mode);
00441     friend const mpreal zeta     (const mpreal& v, mp_rnd_t rnd_mode);
00442     friend const mpreal erf      (const mpreal& v, mp_rnd_t rnd_mode);
00443     friend const mpreal erfc     (const mpreal& v, mp_rnd_t rnd_mode);
00444     friend const mpreal besselj0 (const mpreal& v, mp_rnd_t rnd_mode); 
00445     friend const mpreal besselj1 (const mpreal& v, mp_rnd_t rnd_mode); 
00446     friend const mpreal besseljn (long n, const mpreal& v, mp_rnd_t rnd_mode);
00447     friend const mpreal bessely0 (const mpreal& v, mp_rnd_t rnd_mode);
00448     friend const mpreal bessely1 (const mpreal& v, mp_rnd_t rnd_mode);
00449     friend const mpreal besselyn (long n, const mpreal& v, mp_rnd_t rnd_mode); 
00450     friend const mpreal fma      (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode);
00451     friend const mpreal fms      (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode);
00452     friend const mpreal agm      (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode);
00453     friend const mpreal sum      (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode);
00454     friend int sgn(const mpreal& v); // returns -1 or +1
00455 
00456 // MPFR 2.4.0 Specifics
00457 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
00458     friend int          sinh_cosh   (mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode);
00459     friend const mpreal li2         (const mpreal& v,                       mp_rnd_t rnd_mode);
00460     friend const mpreal fmod        (const mpreal& x, const mpreal& y,      mp_rnd_t rnd_mode);
00461     friend const mpreal rec_sqrt    (const mpreal& v,                       mp_rnd_t rnd_mode);
00462 
00463     // MATLAB's semantic equivalents
00464     friend const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Remainder after division
00465     friend const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Modulus after division
00466 #endif
00467 
00468 // MPFR 3.0.0 Specifics
00469 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
00470     friend const mpreal digamma (const mpreal& v,        mp_rnd_t rnd_mode);
00471     friend const mpreal ai      (const mpreal& v,        mp_rnd_t rnd_mode);
00472     friend const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode);     // use gmp_randinit_default() to init state, gmp_randclear() to clear
00473     friend const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode);     // use gmp_randinit_default() to init state, gmp_randclear() to clear
00474     friend const mpreal grandom (unsigned int seed);
00475 #endif
00476     
00477     // Uniformly distributed random number generation in [0,1] using
00478     // Mersenne-Twister algorithm by default.
00479     // Use parameter to setup seed, e.g.: random((unsigned)time(NULL))
00480     // Check urandom() for more precise control.
00481     friend const mpreal random(unsigned int seed);
00482 
00483     // Exponent and mantissa manipulation
00484     friend const mpreal frexp(const mpreal& v, mp_exp_t* exp);    
00485     friend const mpreal ldexp(const mpreal& v, mp_exp_t exp);
00486 
00487     // Splits mpreal value into fractional and integer parts.
00488     // Returns fractional part and stores integer part in n.
00489     friend const mpreal modf(const mpreal& v, mpreal& n);    
00490 
00491     // Constants
00492     // don't forget to call mpfr_free_cache() for every thread where you are using const-functions
00493     friend const mpreal const_log2      (mp_prec_t prec, mp_rnd_t rnd_mode);
00494     friend const mpreal const_pi        (mp_prec_t prec, mp_rnd_t rnd_mode);
00495     friend const mpreal const_euler     (mp_prec_t prec, mp_rnd_t rnd_mode);
00496     friend const mpreal const_catalan   (mp_prec_t prec, mp_rnd_t rnd_mode);
00497 
00498     // returns +inf iff sign>=0 otherwise -inf
00499     friend const mpreal const_infinity(int sign, mp_prec_t prec);
00500 
00501     // Output/ Input
00502     friend std::ostream& operator<<(std::ostream& os, const mpreal& v);
00503     friend std::istream& operator>>(std::istream& is, mpreal& v);
00504 
00505     // Integer Related Functions
00506     friend const mpreal rint (const mpreal& v, mp_rnd_t rnd_mode);
00507     friend const mpreal ceil (const mpreal& v);
00508     friend const mpreal floor(const mpreal& v);
00509     friend const mpreal round(const mpreal& v);
00510     friend const mpreal trunc(const mpreal& v);
00511     friend const mpreal rint_ceil   (const mpreal& v, mp_rnd_t rnd_mode);
00512     friend const mpreal rint_floor  (const mpreal& v, mp_rnd_t rnd_mode);
00513     friend const mpreal rint_round  (const mpreal& v, mp_rnd_t rnd_mode);
00514     friend const mpreal rint_trunc  (const mpreal& v, mp_rnd_t rnd_mode);
00515     friend const mpreal frac        (const mpreal& v, mp_rnd_t rnd_mode);
00516     friend const mpreal remainder   (         const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
00517     friend const mpreal remquo      (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
00518     
00519     // Miscellaneous Functions
00520     friend const mpreal nexttoward (const mpreal& x, const mpreal& y);
00521     friend const mpreal nextabove  (const mpreal& x);
00522     friend const mpreal nextbelow  (const mpreal& x);
00523 
00524     // use gmp_randinit_default() to init state, gmp_randclear() to clear
00525     friend const mpreal urandomb (gmp_randstate_t& state); 
00526 
00527 // MPFR < 2.4.2 Specifics
00528 #if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2))
00529     friend const mpreal random2 (mp_size_t size, mp_exp_t exp);
00530 #endif
00531 
00532     // Instance Checkers
00533     friend bool isnan    (const mpreal& v);
00534     friend bool isinf    (const mpreal& v);
00535     friend bool isfinite (const mpreal& v);
00536 
00537     friend bool isnum    (const mpreal& v);
00538     friend bool iszero   (const mpreal& v);
00539     friend bool isint    (const mpreal& v);
00540 
00541 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
00542     friend bool isregular(const mpreal& v);
00543 #endif
00544 
00545     // Set/Get instance properties
00546     inline mp_prec_t    get_prec() const;
00547     inline void         set_prec(mp_prec_t prec, mp_rnd_t rnd_mode = get_default_rnd());    // Change precision with rounding mode
00548 
00549     // Aliases for get_prec(), set_prec() - needed for compatibility with std::complex<mpreal> interface
00550     inline mpreal&      setPrecision(int Precision, mp_rnd_t RoundingMode = get_default_rnd());
00551     inline int          getPrecision() const;
00552     
00553     // Set mpreal to +/- inf, NaN, +/-0
00554     mpreal&        setInf  (int Sign = +1);    
00555     mpreal&        setNan  ();
00556     mpreal&        setZero (int Sign = +1);
00557     mpreal&        setSign (int Sign, mp_rnd_t RoundingMode = get_default_rnd());
00558 
00559     //Exponent
00560     mp_exp_t get_exp();
00561     int set_exp(mp_exp_t e);
00562     int check_range  (int t, mp_rnd_t rnd_mode = get_default_rnd());
00563     int subnormalize (int t,mp_rnd_t rnd_mode = get_default_rnd());
00564 
00565     // Inexact conversion from float
00566     inline bool fits_in_bits(double x, int n);
00567 
00568     // Set/Get global properties
00569     static void            set_default_prec(mp_prec_t prec);
00570     static void            set_default_rnd(mp_rnd_t rnd_mode);
00571 
00572     static mp_exp_t  get_emin (void);
00573     static mp_exp_t  get_emax (void);
00574     static mp_exp_t  get_emin_min (void);
00575     static mp_exp_t  get_emin_max (void);
00576     static mp_exp_t  get_emax_min (void);
00577     static mp_exp_t  get_emax_max (void);
00578     static int       set_emin (mp_exp_t exp);
00579     static int       set_emax (mp_exp_t exp);
00580 
00581     // Efficient swapping of two mpreal values - needed for std algorithms
00582     friend void swap(mpreal& x, mpreal& y);
00583     
00584     friend const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
00585     friend const mpreal fmin(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
00586 
00587 private:
00588     // Human friendly Debug Preview in Visual Studio.
00589     // Put one of these lines:
00590     //
00591     // mpfr::mpreal=<DebugView>                              ; Show value only
00592     // mpfr::mpreal=<DebugView>, <mp[0]._mpfr_prec,u>bits    ; Show value & precision
00593     // 
00594     // at the beginning of
00595     // [Visual Studio Installation Folder]\Common7\Packages\Debugger\autoexp.dat
00596     MPREAL_MSVC_DEBUGVIEW_DATA
00597 
00598     // "Smart" resources deallocation. Checks if instance initialized before deletion.
00599     void clear(::mpfr_ptr);
00600 };
00601 
00603 // Exceptions
00604 class conversion_overflow : public std::exception {
00605 public:
00606     std::string why() { return "inexact conversion from floating point"; }
00607 };
00608 
00610 // Constructors & converters
00611 // Default constructor: creates mp number and initializes it to 0.
00612 inline mpreal::mpreal() 
00613 { 
00614     mpfr_init2 (mpfr_ptr(), mpreal::get_default_prec()); 
00615     mpfr_set_ui(mpfr_ptr(), 0, mpreal::get_default_rnd());
00616 
00617     MPREAL_MSVC_DEBUGVIEW_CODE;
00618 }
00619 
00620 inline mpreal::mpreal(const mpreal& u) 
00621 {
00622     mpfr_init2(mpfr_ptr(),mpfr_get_prec(u.mpfr_srcptr()));
00623     mpfr_set  (mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd());
00624 
00625     MPREAL_MSVC_DEBUGVIEW_CODE;
00626 }
00627 
00628 #ifdef MPREAL_HAVE_MOVE_SUPPORT
00629 inline mpreal::mpreal(mpreal&& other)
00630 {
00631     mpfr_set_uninitialized(mpfr_ptr());     // make sure "other" holds no pinter to actual data 
00632     mpfr_swap(mpfr_ptr(), other.mpfr_ptr());
00633 
00634     MPREAL_MSVC_DEBUGVIEW_CODE;
00635 }
00636 
00637 inline mpreal& mpreal::operator=(mpreal&& other)
00638 {
00639     mpfr_swap(mpfr_ptr(), other.mpfr_ptr());
00640 
00641     MPREAL_MSVC_DEBUGVIEW_CODE;
00642     return *this;
00643 }
00644 #endif
00645 
00646 inline mpreal::mpreal(const mpfr_t  u, bool shared)
00647 {
00648     if(shared)
00649     {
00650         std::memcpy(mpfr_ptr(), u, sizeof(mpfr_t));
00651     }
00652     else
00653     {
00654         mpfr_init2(mpfr_ptr(), mpfr_get_prec(u));
00655         mpfr_set  (mpfr_ptr(), u, mpreal::get_default_rnd());
00656     }
00657 
00658     MPREAL_MSVC_DEBUGVIEW_CODE;
00659 }
00660 
00661 inline mpreal::mpreal(const mpf_t u)
00662 {
00663     mpfr_init2(mpfr_ptr(),(mp_prec_t) mpf_get_prec(u)); // (gmp: mp_bitcnt_t) unsigned long -> long (mpfr: mp_prec_t)
00664     mpfr_set_f(mpfr_ptr(),u,mpreal::get_default_rnd());
00665 
00666     MPREAL_MSVC_DEBUGVIEW_CODE;
00667 }
00668 
00669 inline mpreal::mpreal(const mpz_t u, mp_prec_t prec, mp_rnd_t mode)
00670 {
00671     mpfr_init2(mpfr_ptr(), prec);
00672     mpfr_set_z(mpfr_ptr(), u, mode);
00673 
00674     MPREAL_MSVC_DEBUGVIEW_CODE;
00675 }
00676 
00677 inline mpreal::mpreal(const mpq_t u, mp_prec_t prec, mp_rnd_t mode)
00678 {
00679     mpfr_init2(mpfr_ptr(), prec);
00680     mpfr_set_q(mpfr_ptr(), u, mode);
00681 
00682     MPREAL_MSVC_DEBUGVIEW_CODE;
00683 }
00684 
00685 inline mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode)
00686 {
00687      mpfr_init2(mpfr_ptr(), prec);
00688 
00689 #if (MPREAL_DOUBLE_BITS_OVERFLOW > -1)
00690   if(fits_in_bits(u, MPREAL_DOUBLE_BITS_OVERFLOW))
00691   {
00692     mpfr_set_d(mpfr_ptr(), u, mode);
00693   }else
00694     throw conversion_overflow();
00695 #else
00696   mpfr_set_d(mpfr_ptr(), u, mode);
00697 #endif
00698 
00699     MPREAL_MSVC_DEBUGVIEW_CODE;
00700 }
00701 
00702 inline mpreal::mpreal(const long double u, mp_prec_t prec, mp_rnd_t mode)
00703 { 
00704     mpfr_init2 (mpfr_ptr(), prec);
00705     mpfr_set_ld(mpfr_ptr(), u, mode);
00706 
00707     MPREAL_MSVC_DEBUGVIEW_CODE;
00708 }
00709 
00710 inline mpreal::mpreal(const unsigned long int u, mp_prec_t prec, mp_rnd_t mode)
00711 { 
00712     mpfr_init2 (mpfr_ptr(), prec);
00713     mpfr_set_ui(mpfr_ptr(), u, mode);
00714 
00715     MPREAL_MSVC_DEBUGVIEW_CODE;
00716 }
00717 
00718 inline mpreal::mpreal(const unsigned int u, mp_prec_t prec, mp_rnd_t mode)
00719 { 
00720     mpfr_init2 (mpfr_ptr(), prec);
00721     mpfr_set_ui(mpfr_ptr(), u, mode);
00722 
00723     MPREAL_MSVC_DEBUGVIEW_CODE;
00724 }
00725 
00726 inline mpreal::mpreal(const long int u, mp_prec_t prec, mp_rnd_t mode)
00727 { 
00728     mpfr_init2 (mpfr_ptr(), prec);
00729     mpfr_set_si(mpfr_ptr(), u, mode);
00730 
00731     MPREAL_MSVC_DEBUGVIEW_CODE;
00732 }
00733 
00734 inline mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode)
00735 { 
00736     mpfr_init2 (mpfr_ptr(), prec);
00737     mpfr_set_si(mpfr_ptr(), u, mode);
00738 
00739     MPREAL_MSVC_DEBUGVIEW_CODE;
00740 }
00741 
00742 #if defined (MPREAL_HAVE_INT64_SUPPORT)
00743 inline mpreal::mpreal(const uint64_t u, mp_prec_t prec, mp_rnd_t mode)
00744 {
00745     mpfr_init2 (mpfr_ptr(), prec);
00746     mpfr_set_uj(mpfr_ptr(), u, mode); 
00747 
00748     MPREAL_MSVC_DEBUGVIEW_CODE;
00749 }
00750 
00751 inline mpreal::mpreal(const int64_t u, mp_prec_t prec, mp_rnd_t mode)
00752 {
00753     mpfr_init2 (mpfr_ptr(), prec);
00754     mpfr_set_sj(mpfr_ptr(), u, mode); 
00755 
00756     MPREAL_MSVC_DEBUGVIEW_CODE;
00757 }
00758 #endif
00759 
00760 inline mpreal::mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode)
00761 {
00762     mpfr_init2  (mpfr_ptr(), prec);
00763     mpfr_set_str(mpfr_ptr(), s, base, mode); 
00764 
00765     MPREAL_MSVC_DEBUGVIEW_CODE;
00766 }
00767 
00768 inline mpreal::mpreal(const std::string& s, mp_prec_t prec, int base, mp_rnd_t mode)
00769 {
00770     mpfr_init2  (mpfr_ptr(), prec);
00771     mpfr_set_str(mpfr_ptr(), s.c_str(), base, mode); 
00772 
00773     MPREAL_MSVC_DEBUGVIEW_CODE;
00774 }
00775 
00776 inline void mpreal::clear(::mpfr_ptr x)
00777 {
00778 #ifdef MPREAL_HAVE_MOVE_SUPPORT
00779     if(mpfr_is_initialized(x)) 
00780 #endif
00781     mpfr_clear(x);
00782 }
00783 
00784 inline mpreal::~mpreal() 
00785 { 
00786     clear(mpfr_ptr());
00787 }                           
00788 
00789 // internal namespace needed for template magic
00790 namespace internal{
00791 
00792     // Use SFINAE to restrict arithmetic operations instantiation only for numeric types
00793     // This is needed for smooth integration with libraries based on expression templates, like Eigen.
00794     // TODO: Do the same for boolean operators.
00795     template <typename ArgumentType> struct result_type {};    
00796     
00797     template <> struct result_type<mpreal>              {typedef mpreal type;};    
00798     template <> struct result_type<mpz_t>               {typedef mpreal type;};    
00799     template <> struct result_type<mpq_t>               {typedef mpreal type;};    
00800     template <> struct result_type<long double>         {typedef mpreal type;};    
00801     template <> struct result_type<double>              {typedef mpreal type;};    
00802     template <> struct result_type<unsigned long int>   {typedef mpreal type;};    
00803     template <> struct result_type<unsigned int>        {typedef mpreal type;};    
00804     template <> struct result_type<long int>            {typedef mpreal type;};    
00805     template <> struct result_type<int>                 {typedef mpreal type;};    
00806 
00807 #if defined (MPREAL_HAVE_INT64_SUPPORT)
00808     template <> struct result_type<int64_t  >           {typedef mpreal type;};    
00809     template <> struct result_type<uint64_t >           {typedef mpreal type;};    
00810 #endif
00811 }
00812 
00813 // + Addition
00814 template <typename Rhs> 
00815 inline const typename internal::result_type<Rhs>::type 
00816     operator+(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) += rhs;    }
00817 
00818 template <typename Lhs> 
00819 inline const typename internal::result_type<Lhs>::type 
00820     operator+(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) += lhs;    } 
00821 
00822 // - Subtraction
00823 template <typename Rhs> 
00824 inline const typename internal::result_type<Rhs>::type 
00825     operator-(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) -= rhs;    }
00826 
00827 template <typename Lhs> 
00828 inline const typename internal::result_type<Lhs>::type 
00829     operator-(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) -= rhs;    }
00830 
00831 // * Multiplication
00832 template <typename Rhs> 
00833 inline const typename internal::result_type<Rhs>::type 
00834     operator*(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) *= rhs;    }
00835 
00836 template <typename Lhs> 
00837 inline const typename internal::result_type<Lhs>::type 
00838     operator*(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) *= lhs;    } 
00839 
00840 // / Division
00841 template <typename Rhs> 
00842 inline const typename internal::result_type<Rhs>::type 
00843     operator/(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) /= rhs;    }
00844 
00845 template <typename Lhs> 
00846 inline const typename internal::result_type<Lhs>::type 
00847     operator/(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) /= rhs;    }
00848 
00850 // sqrt
00851 const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00852 const mpreal sqrt(const long int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00853 const mpreal sqrt(const int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00854 const mpreal sqrt(const long double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00855 const mpreal sqrt(const double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00856 
00857 // abs
00858 inline const mpreal abs(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd());
00859 
00861 // pow
00862 const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00863 const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00864 const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00865 const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00866 
00867 const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00868 const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00869 const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00870 const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00871 const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00872 
00873 const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00874 const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00875 const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00876 const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00877 const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00878 
00879 const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00880 const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00881 const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00882 const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00883 const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00884 const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00885 
00886 const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00887 const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00888 const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00889 const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00890 const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00891 const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00892 
00893 const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00894 const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00895 const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00896 const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); 
00897 const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00898 const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); 
00899 
00900 const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());    
00901 const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00902 const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00903 const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00904 const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00905 
00906 const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());    
00907 const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00908 const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00909 const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00910 const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00911 
00912 inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00913 inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00914 inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00915 inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
00916 
00918 // Estimate machine epsilon for the given precision
00919 // Returns smallest eps such that 1.0 + eps != 1.0
00920 inline mpreal machine_epsilon(mp_prec_t prec = mpreal::get_default_prec());
00921 
00922 // Returns smallest eps such that x + eps != x (relative machine epsilon)
00923 inline mpreal machine_epsilon(const mpreal& x);        
00924 
00925 // Gives max & min values for the required precision, 
00926 // minval is 'safe' meaning 1 / minval does not overflow
00927 // maxval is 'safe' meaning 1 / maxval does not underflow
00928 inline mpreal minval(mp_prec_t prec = mpreal::get_default_prec());
00929 inline mpreal maxval(mp_prec_t prec = mpreal::get_default_prec());
00930 
00931 // 'Dirty' equality check 1: |a-b| < min{|a|,|b|} * eps
00932 inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps);
00933 
00934 // 'Dirty' equality check 2: |a-b| < min{|a|,|b|} * eps( min{|a|,|b|} )
00935 inline bool isEqualFuzzy(const mpreal& a, const mpreal& b);
00936 
00937 // 'Bitwise' equality check
00938 //  maxUlps - a and b can be apart by maxUlps binary numbers. 
00939 inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps);
00940 
00942 //     Convert precision in 'bits' to decimal digits and vice versa.
00943 //        bits   = ceil(digits*log[2](10))
00944 //        digits = floor(bits*log[10](2))
00945 
00946 inline mp_prec_t digits2bits(int d);
00947 inline int       bits2digits(mp_prec_t b);
00948 
00950 // min, max
00951 const mpreal (max)(const mpreal& x, const mpreal& y);
00952 const mpreal (min)(const mpreal& x, const mpreal& y);
00953 
00955 // Implementation
00957 
00959 // Operators - Assignment
00960 inline mpreal& mpreal::operator=(const mpreal& v)
00961 {
00962     if (this != &v)
00963     {
00964     mp_prec_t tp = mpfr_get_prec(  mpfr_srcptr());
00965     mp_prec_t vp = mpfr_get_prec(v.mpfr_srcptr());
00966 
00967     if(tp != vp){
00968       clear(mpfr_ptr());
00969       mpfr_init2(mpfr_ptr(), vp);
00970     }
00971 
00972         mpfr_set(mpfr_ptr(), v.mpfr_srcptr(), mpreal::get_default_rnd());
00973 
00974         MPREAL_MSVC_DEBUGVIEW_CODE;
00975     }
00976     return *this;
00977 }
00978 
00979 inline mpreal& mpreal::operator=(const mpf_t v)
00980 {
00981     mpfr_set_f(mpfr_ptr(), v, mpreal::get_default_rnd());
00982     
00983     MPREAL_MSVC_DEBUGVIEW_CODE;
00984     return *this;
00985 }
00986 
00987 inline mpreal& mpreal::operator=(const mpz_t v)
00988 {
00989     mpfr_set_z(mpfr_ptr(), v, mpreal::get_default_rnd());
00990     
00991     MPREAL_MSVC_DEBUGVIEW_CODE;
00992     return *this;
00993 }
00994 
00995 inline mpreal& mpreal::operator=(const mpq_t v)
00996 {
00997     mpfr_set_q(mpfr_ptr(), v, mpreal::get_default_rnd());
00998 
00999     MPREAL_MSVC_DEBUGVIEW_CODE;
01000     return *this;
01001 }
01002 
01003 inline mpreal& mpreal::operator=(const long double v)        
01004 {    
01005     mpfr_set_ld(mpfr_ptr(), v, mpreal::get_default_rnd());
01006 
01007     MPREAL_MSVC_DEBUGVIEW_CODE;
01008     return *this;
01009 }
01010 
01011 inline mpreal& mpreal::operator=(const double v)                
01012 {   
01013 #if (MPREAL_DOUBLE_BITS_OVERFLOW > -1)
01014   if(fits_in_bits(v, MPREAL_DOUBLE_BITS_OVERFLOW))
01015   {
01016     mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd());
01017   }else
01018     throw conversion_overflow();
01019 #else
01020   mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd());
01021 #endif
01022 
01023   MPREAL_MSVC_DEBUGVIEW_CODE;
01024     return *this;
01025 }
01026 
01027 inline mpreal& mpreal::operator=(const unsigned long int v)    
01028 {    
01029     mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd());    
01030 
01031     MPREAL_MSVC_DEBUGVIEW_CODE;
01032     return *this;
01033 }
01034 
01035 inline mpreal& mpreal::operator=(const unsigned int v)        
01036 {    
01037     mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd());    
01038 
01039     MPREAL_MSVC_DEBUGVIEW_CODE;
01040     return *this;
01041 }
01042 
01043 inline mpreal& mpreal::operator=(const long int v)            
01044 {    
01045     mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd());    
01046 
01047     MPREAL_MSVC_DEBUGVIEW_CODE;
01048     return *this;
01049 }
01050 
01051 inline mpreal& mpreal::operator=(const int v)
01052 {    
01053     mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd());    
01054 
01055     MPREAL_MSVC_DEBUGVIEW_CODE;
01056     return *this;
01057 }
01058 
01059 inline mpreal& mpreal::operator=(const char* s)
01060 {
01061     // Use other converters for more precise control on base & precision & rounding:
01062     //
01063     //        mpreal(const char* s,        mp_prec_t prec, int base, mp_rnd_t mode)
01064     //        mpreal(const std::string& s,mp_prec_t prec, int base, mp_rnd_t mode)
01065     //
01066     // Here we assume base = 10 and we use precision of target variable.
01067 
01068     mpfr_t t;
01069 
01070     mpfr_init2(t, mpfr_get_prec(mpfr_srcptr()));
01071 
01072     if(0 == mpfr_set_str(t, s, 10, mpreal::get_default_rnd()))
01073     {
01074         mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd()); 
01075         MPREAL_MSVC_DEBUGVIEW_CODE;
01076     }
01077 
01078     clear(t);
01079     return *this;
01080 }
01081 
01082 inline mpreal& mpreal::operator=(const std::string& s)
01083 {
01084     // Use other converters for more precise control on base & precision & rounding:
01085     //
01086     //        mpreal(const char* s,        mp_prec_t prec, int base, mp_rnd_t mode)
01087     //        mpreal(const std::string& s,mp_prec_t prec, int base, mp_rnd_t mode)
01088     //
01089     // Here we assume base = 10 and we use precision of target variable.
01090 
01091     mpfr_t t;
01092 
01093     mpfr_init2(t, mpfr_get_prec(mpfr_srcptr()));
01094 
01095     if(0 == mpfr_set_str(t, s.c_str(), 10, mpreal::get_default_rnd()))
01096     {
01097         mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd()); 
01098         MPREAL_MSVC_DEBUGVIEW_CODE;
01099     }
01100 
01101     clear(t);
01102     return *this;
01103 }
01104 
01105 
01107 // + Addition
01108 inline mpreal& mpreal::operator+=(const mpreal& v)
01109 {
01110     mpfr_add(mpfr_ptr(), mpfr_srcptr(), v.mpfr_srcptr(), mpreal::get_default_rnd());
01111     MPREAL_MSVC_DEBUGVIEW_CODE;
01112     return *this;
01113 }
01114 
01115 inline mpreal& mpreal::operator+=(const mpf_t u)
01116 {
01117     *this += mpreal(u);
01118     MPREAL_MSVC_DEBUGVIEW_CODE;
01119     return *this;
01120 }
01121 
01122 inline mpreal& mpreal::operator+=(const mpz_t u)
01123 {
01124     mpfr_add_z(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01125     MPREAL_MSVC_DEBUGVIEW_CODE;
01126     return *this;
01127 }
01128 
01129 inline mpreal& mpreal::operator+=(const mpq_t u)
01130 {
01131     mpfr_add_q(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01132     MPREAL_MSVC_DEBUGVIEW_CODE;
01133     return *this;
01134 }
01135 
01136 inline mpreal& mpreal::operator+= (const long double u)
01137 {
01138     *this += mpreal(u);    
01139     MPREAL_MSVC_DEBUGVIEW_CODE;
01140     return *this;    
01141 }
01142 
01143 inline mpreal& mpreal::operator+= (const double u)
01144 {
01145 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
01146     mpfr_add_d(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01147 #else
01148     *this += mpreal(u);
01149 #endif
01150 
01151     MPREAL_MSVC_DEBUGVIEW_CODE;
01152     return *this;
01153 }
01154 
01155 inline mpreal& mpreal::operator+=(const unsigned long int u)
01156 {
01157     mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01158     MPREAL_MSVC_DEBUGVIEW_CODE;
01159     return *this;
01160 }
01161 
01162 inline mpreal& mpreal::operator+=(const unsigned int u)
01163 {
01164     mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01165     MPREAL_MSVC_DEBUGVIEW_CODE;
01166     return *this;
01167 }
01168 
01169 inline mpreal& mpreal::operator+=(const long int u)
01170 {
01171     mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01172     MPREAL_MSVC_DEBUGVIEW_CODE;
01173     return *this;
01174 }
01175 
01176 inline mpreal& mpreal::operator+=(const int u)
01177 {
01178     mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01179     MPREAL_MSVC_DEBUGVIEW_CODE;
01180     return *this;
01181 }
01182 
01183 #if defined (MPREAL_HAVE_INT64_SUPPORT)
01184 inline mpreal& mpreal::operator+=(const int64_t  u){    *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
01185 inline mpreal& mpreal::operator+=(const uint64_t u){    *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
01186 inline mpreal& mpreal::operator-=(const int64_t  u){    *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
01187 inline mpreal& mpreal::operator-=(const uint64_t u){    *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
01188 inline mpreal& mpreal::operator*=(const int64_t  u){    *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
01189 inline mpreal& mpreal::operator*=(const uint64_t u){    *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
01190 inline mpreal& mpreal::operator/=(const int64_t  u){    *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
01191 inline mpreal& mpreal::operator/=(const uint64_t u){    *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
01192 #endif 
01193 
01194 inline const mpreal mpreal::operator+()const    {    return mpreal(*this); }
01195 
01196 inline const mpreal operator+(const mpreal& a, const mpreal& b)
01197 {
01198   mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr())));
01199   mpfr_add(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd());
01200   return c;
01201 }
01202 
01203 inline mpreal& mpreal::operator++() 
01204 {
01205     return *this += 1;
01206 }
01207 
01208 inline const mpreal mpreal::operator++ (int)
01209 {
01210     mpreal x(*this);
01211     *this += 1;
01212     return x;
01213 }
01214 
01215 inline mpreal& mpreal::operator--() 
01216 {
01217     return *this -= 1;
01218 }
01219 
01220 inline const mpreal mpreal::operator-- (int)
01221 {
01222     mpreal x(*this);
01223     *this -= 1;
01224     return x;
01225 }
01226 
01228 // - Subtraction
01229 inline mpreal& mpreal::operator-=(const mpreal& v)
01230 {
01231     mpfr_sub(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd());
01232     MPREAL_MSVC_DEBUGVIEW_CODE;
01233     return *this;
01234 }
01235 
01236 inline mpreal& mpreal::operator-=(const mpz_t v)
01237 {
01238     mpfr_sub_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01239     MPREAL_MSVC_DEBUGVIEW_CODE;
01240     return *this;
01241 }
01242 
01243 inline mpreal& mpreal::operator-=(const mpq_t v)
01244 {
01245     mpfr_sub_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01246     MPREAL_MSVC_DEBUGVIEW_CODE;
01247     return *this;
01248 }
01249 
01250 inline mpreal& mpreal::operator-=(const long double v)
01251 {
01252     *this -= mpreal(v);    
01253     MPREAL_MSVC_DEBUGVIEW_CODE;
01254     return *this;    
01255 }
01256 
01257 inline mpreal& mpreal::operator-=(const double v)
01258 {
01259 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
01260     mpfr_sub_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01261 #else
01262     *this -= mpreal(v);    
01263 #endif
01264 
01265     MPREAL_MSVC_DEBUGVIEW_CODE;
01266     return *this;
01267 }
01268 
01269 inline mpreal& mpreal::operator-=(const unsigned long int v)
01270 {
01271     mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01272     MPREAL_MSVC_DEBUGVIEW_CODE;
01273     return *this;
01274 }
01275 
01276 inline mpreal& mpreal::operator-=(const unsigned int v)
01277 {
01278     mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01279     MPREAL_MSVC_DEBUGVIEW_CODE;
01280     return *this;
01281 }
01282 
01283 inline mpreal& mpreal::operator-=(const long int v)
01284 {
01285     mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01286     MPREAL_MSVC_DEBUGVIEW_CODE;
01287     return *this;
01288 }
01289 
01290 inline mpreal& mpreal::operator-=(const int v)
01291 {
01292     mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01293     MPREAL_MSVC_DEBUGVIEW_CODE;
01294     return *this;
01295 }
01296 
01297 inline const mpreal mpreal::operator-()const
01298 {
01299     mpreal u(*this);
01300     mpfr_neg(u.mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd());
01301     return u;
01302 }
01303 
01304 inline const mpreal operator-(const mpreal& a, const mpreal& b)
01305 {
01306   mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr())));
01307   mpfr_sub(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd());
01308   return c;
01309 }
01310 
01311 inline const mpreal operator-(const double  b, const mpreal& a)
01312 {
01313 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
01314     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
01315     mpfr_d_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01316     return x;
01317 #else
01318     mpreal x(b, mpfr_get_prec(a.mpfr_ptr()));
01319     x -= a;
01320     return x;
01321 #endif
01322 }
01323 
01324 inline const mpreal operator-(const unsigned long int b, const mpreal& a)
01325 {
01326     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
01327     mpfr_ui_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01328     return x;
01329 }
01330 
01331 inline const mpreal operator-(const unsigned int b, const mpreal& a)
01332 {
01333     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
01334     mpfr_ui_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01335     return x;
01336 }
01337 
01338 inline const mpreal operator-(const long int b, const mpreal& a)
01339 {
01340     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
01341     mpfr_si_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01342     return x;
01343 }
01344 
01345 inline const mpreal operator-(const int b, const mpreal& a)
01346 {
01347     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
01348     mpfr_si_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01349     return x;
01350 }
01351 
01353 // * Multiplication
01354 inline mpreal& mpreal::operator*= (const mpreal& v)
01355 {
01356     mpfr_mul(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd());
01357     MPREAL_MSVC_DEBUGVIEW_CODE;
01358     return *this;
01359 }
01360 
01361 inline mpreal& mpreal::operator*=(const mpz_t v)
01362 {
01363     mpfr_mul_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01364     MPREAL_MSVC_DEBUGVIEW_CODE;
01365     return *this;
01366 }
01367 
01368 inline mpreal& mpreal::operator*=(const mpq_t v)
01369 {
01370     mpfr_mul_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01371     MPREAL_MSVC_DEBUGVIEW_CODE;
01372     return *this;
01373 }
01374 
01375 inline mpreal& mpreal::operator*=(const long double v)
01376 {
01377     *this *= mpreal(v);    
01378     MPREAL_MSVC_DEBUGVIEW_CODE;
01379     return *this;    
01380 }
01381 
01382 inline mpreal& mpreal::operator*=(const double v)
01383 {
01384 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
01385     mpfr_mul_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01386 #else
01387     *this *= mpreal(v);    
01388 #endif
01389     MPREAL_MSVC_DEBUGVIEW_CODE;
01390     return *this;
01391 }
01392 
01393 inline mpreal& mpreal::operator*=(const unsigned long int v)
01394 {
01395     mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01396     MPREAL_MSVC_DEBUGVIEW_CODE;
01397     return *this;
01398 }
01399 
01400 inline mpreal& mpreal::operator*=(const unsigned int v)
01401 {
01402     mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01403     MPREAL_MSVC_DEBUGVIEW_CODE;
01404     return *this;
01405 }
01406 
01407 inline mpreal& mpreal::operator*=(const long int v)
01408 {
01409     mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01410     MPREAL_MSVC_DEBUGVIEW_CODE;
01411     return *this;
01412 }
01413 
01414 inline mpreal& mpreal::operator*=(const int v)
01415 {
01416     mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01417     MPREAL_MSVC_DEBUGVIEW_CODE;
01418     return *this;
01419 }
01420 
01421 inline const mpreal operator*(const mpreal& a, const mpreal& b)
01422 {
01423   mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr())));
01424   mpfr_mul(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd());
01425   return c;
01426 }
01427 
01429 // / Division
01430 inline mpreal& mpreal::operator/=(const mpreal& v)
01431 {
01432     mpfr_div(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd());
01433     MPREAL_MSVC_DEBUGVIEW_CODE;
01434     return *this;
01435 }
01436 
01437 inline mpreal& mpreal::operator/=(const mpz_t v)
01438 {
01439     mpfr_div_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01440     MPREAL_MSVC_DEBUGVIEW_CODE;
01441     return *this;
01442 }
01443 
01444 inline mpreal& mpreal::operator/=(const mpq_t v)
01445 {
01446     mpfr_div_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01447     MPREAL_MSVC_DEBUGVIEW_CODE;
01448     return *this;
01449 }
01450 
01451 inline mpreal& mpreal::operator/=(const long double v)
01452 {
01453     *this /= mpreal(v);
01454     MPREAL_MSVC_DEBUGVIEW_CODE;
01455     return *this;    
01456 }
01457 
01458 inline mpreal& mpreal::operator/=(const double v)
01459 {
01460 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
01461     mpfr_div_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01462 #else
01463     *this /= mpreal(v);    
01464 #endif
01465     MPREAL_MSVC_DEBUGVIEW_CODE;
01466     return *this;
01467 }
01468 
01469 inline mpreal& mpreal::operator/=(const unsigned long int v)
01470 {
01471     mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01472     MPREAL_MSVC_DEBUGVIEW_CODE;
01473     return *this;
01474 }
01475 
01476 inline mpreal& mpreal::operator/=(const unsigned int v)
01477 {
01478     mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01479     MPREAL_MSVC_DEBUGVIEW_CODE;
01480     return *this;
01481 }
01482 
01483 inline mpreal& mpreal::operator/=(const long int v)
01484 {
01485     mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01486     MPREAL_MSVC_DEBUGVIEW_CODE;
01487     return *this;
01488 }
01489 
01490 inline mpreal& mpreal::operator/=(const int v)
01491 {
01492     mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
01493     MPREAL_MSVC_DEBUGVIEW_CODE;
01494     return *this;
01495 }
01496 
01497 inline const mpreal operator/(const mpreal& a, const mpreal& b)
01498 {
01499   mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_srcptr()), mpfr_get_prec(b.mpfr_srcptr())));
01500   mpfr_div(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd());
01501   return c;
01502 }
01503 
01504 inline const mpreal operator/(const unsigned long int b, const mpreal& a)
01505 {
01506     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
01507     mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01508     return x;
01509 }
01510 
01511 inline const mpreal operator/(const unsigned int b, const mpreal& a)
01512 {
01513     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
01514     mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01515     return x;
01516 }
01517 
01518 inline const mpreal operator/(const long int b, const mpreal& a)
01519 {
01520     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
01521     mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01522     return x;
01523 }
01524 
01525 inline const mpreal operator/(const int b, const mpreal& a)
01526 {
01527     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
01528     mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01529     return x;
01530 }
01531 
01532 inline const mpreal operator/(const double  b, const mpreal& a)
01533 {
01534 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
01535     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
01536     mpfr_d_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
01537     return x;
01538 #else
01539     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
01540     x /= a;
01541     return x;
01542 #endif
01543 }
01544 
01546 // Shifts operators - Multiplication/Division by power of 2
01547 inline mpreal& mpreal::operator<<=(const unsigned long int u)
01548 {
01549     mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01550     MPREAL_MSVC_DEBUGVIEW_CODE;
01551     return *this;
01552 }
01553 
01554 inline mpreal& mpreal::operator<<=(const unsigned int u)
01555 {
01556     mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast<unsigned long int>(u),mpreal::get_default_rnd());
01557     MPREAL_MSVC_DEBUGVIEW_CODE;
01558     return *this;
01559 }
01560 
01561 inline mpreal& mpreal::operator<<=(const long int u)
01562 {
01563     mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01564     MPREAL_MSVC_DEBUGVIEW_CODE;
01565     return *this;
01566 }
01567 
01568 inline mpreal& mpreal::operator<<=(const int u)
01569 {
01570     mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),static_cast<long int>(u),mpreal::get_default_rnd());
01571     MPREAL_MSVC_DEBUGVIEW_CODE;
01572     return *this;
01573 }
01574 
01575 inline mpreal& mpreal::operator>>=(const unsigned long int u)
01576 {
01577     mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01578     MPREAL_MSVC_DEBUGVIEW_CODE;
01579     return *this;
01580 }
01581 
01582 inline mpreal& mpreal::operator>>=(const unsigned int u)
01583 {
01584     mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast<unsigned long int>(u),mpreal::get_default_rnd());
01585     MPREAL_MSVC_DEBUGVIEW_CODE;
01586     return *this;
01587 }
01588 
01589 inline mpreal& mpreal::operator>>=(const long int u)
01590 {
01591     mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
01592     MPREAL_MSVC_DEBUGVIEW_CODE;
01593     return *this;
01594 }
01595 
01596 inline mpreal& mpreal::operator>>=(const int u)
01597 {
01598     mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),static_cast<long int>(u),mpreal::get_default_rnd());
01599     MPREAL_MSVC_DEBUGVIEW_CODE;
01600     return *this;
01601 }
01602 
01603 inline const mpreal operator<<(const mpreal& v, const unsigned long int k)
01604 {
01605     return mul_2ui(v,k);
01606 }
01607 
01608 inline const mpreal operator<<(const mpreal& v, const unsigned int k)
01609 {
01610     return mul_2ui(v,static_cast<unsigned long int>(k));
01611 }
01612 
01613 inline const mpreal operator<<(const mpreal& v, const long int k)
01614 {
01615     return mul_2si(v,k);
01616 }
01617 
01618 inline const mpreal operator<<(const mpreal& v, const int k)
01619 {
01620     return mul_2si(v,static_cast<long int>(k));
01621 }
01622 
01623 inline const mpreal operator>>(const mpreal& v, const unsigned long int k)
01624 {
01625     return div_2ui(v,k);
01626 }
01627 
01628 inline const mpreal operator>>(const mpreal& v, const long int k)
01629 {
01630     return div_2si(v,k);
01631 }
01632 
01633 inline const mpreal operator>>(const mpreal& v, const unsigned int k)
01634 {
01635     return div_2ui(v,static_cast<unsigned long int>(k));
01636 }
01637 
01638 inline const mpreal operator>>(const mpreal& v, const int k)
01639 {
01640     return div_2si(v,static_cast<long int>(k));
01641 }
01642 
01643 // mul_2ui
01644 inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
01645 {
01646     mpreal x(v);
01647     mpfr_mul_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode);
01648     return x;
01649 }
01650 
01651 // mul_2si
01652 inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode)
01653 {
01654     mpreal x(v);
01655     mpfr_mul_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode);
01656     return x;
01657 }
01658 
01659 inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
01660 {
01661     mpreal x(v);
01662     mpfr_div_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode);
01663     return x;
01664 }
01665 
01666 inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode)
01667 {
01668     mpreal x(v);
01669     mpfr_div_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode);
01670     return x;
01671 }
01672 
01674 //Boolean operators
01675 inline bool operator >  (const mpreal& a, const mpreal& b){    return (mpfr_greater_p       (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
01676 inline bool operator >= (const mpreal& a, const mpreal& b){    return (mpfr_greaterequal_p  (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
01677 inline bool operator <  (const mpreal& a, const mpreal& b){    return (mpfr_less_p          (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
01678 inline bool operator <= (const mpreal& a, const mpreal& b){    return (mpfr_lessequal_p     (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
01679 inline bool operator == (const mpreal& a, const mpreal& b){    return (mpfr_equal_p         (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
01680 inline bool operator != (const mpreal& a, const mpreal& b){    return (mpfr_lessgreater_p   (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
01681 
01682 inline bool operator == (const mpreal& a, const unsigned long int b ){    return (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 );    }
01683 inline bool operator == (const mpreal& a, const unsigned int b      ){    return (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 );    }
01684 inline bool operator == (const mpreal& a, const long int b          ){    return (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 );    }
01685 inline bool operator == (const mpreal& a, const int b               ){    return (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 );    }
01686 inline bool operator == (const mpreal& a, const long double b       ){    return (mpfr_cmp_ld(a.mpfr_srcptr(),b) == 0 );    }
01687 inline bool operator == (const mpreal& a, const double b            ){    return (mpfr_cmp_d (a.mpfr_srcptr(),b) == 0 );    }
01688 
01689 
01690 inline bool isnan    (const mpreal& op){    return (mpfr_nan_p    (op.mpfr_srcptr()) != 0 );    }
01691 inline bool isinf    (const mpreal& op){    return (mpfr_inf_p    (op.mpfr_srcptr()) != 0 );    }
01692 inline bool isfinite (const mpreal& op){    return (mpfr_number_p (op.mpfr_srcptr()) != 0 );    }
01693 inline bool iszero   (const mpreal& op){    return (mpfr_zero_p   (op.mpfr_srcptr()) != 0 );    }
01694 inline bool isint    (const mpreal& op){    return (mpfr_integer_p(op.mpfr_srcptr()) != 0 );    }
01695 
01696 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
01697 inline bool isregular(const mpreal& op){    return (mpfr_regular_p(op.mpfr_srcptr()));}
01698 #endif 
01699 
01701 // Type Converters
01702 inline bool             mpreal::toBool (mp_rnd_t /*mode*/) const   {    return  mpfr_zero_p (mpfr_srcptr()) == 0;     }
01703 inline long             mpreal::toLong   (mp_rnd_t mode)  const    {    return  mpfr_get_si (mpfr_srcptr(), mode);    }
01704 inline unsigned long    mpreal::toULong  (mp_rnd_t mode)  const    {    return  mpfr_get_ui (mpfr_srcptr(), mode);    }
01705 inline float            mpreal::toFloat  (mp_rnd_t mode)  const    {    return  mpfr_get_flt(mpfr_srcptr(), mode);    }
01706 inline double           mpreal::toDouble (mp_rnd_t mode)  const    {    return  mpfr_get_d  (mpfr_srcptr(), mode);    }
01707 inline long double      mpreal::toLDouble(mp_rnd_t mode)  const    {    return  mpfr_get_ld (mpfr_srcptr(), mode);    }
01708 
01709 #if defined (MPREAL_HAVE_INT64_SUPPORT)
01710 inline int64_t      mpreal::toInt64 (mp_rnd_t mode)    const{    return mpfr_get_sj(mpfr_srcptr(), mode);    }
01711 inline uint64_t     mpreal::toUInt64(mp_rnd_t mode)    const{    return mpfr_get_uj(mpfr_srcptr(), mode);    }
01712 #endif
01713 
01714 inline ::mpfr_ptr     mpreal::mpfr_ptr()             { return mp; }
01715 inline ::mpfr_srcptr  mpreal::mpfr_ptr()    const    { return mp; }
01716 inline ::mpfr_srcptr  mpreal::mpfr_srcptr() const    { return mp; }
01717 
01718 template <class T>
01719 inline std::string toString(T t, std::ios_base & (*f)(std::ios_base&))
01720 {
01721     std::ostringstream oss;
01722     oss << f << t;
01723     return oss.str();
01724 }
01725 
01726 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
01727 
01728 inline std::string mpreal::toString(const std::string& format) const
01729 {
01730     char *s = NULL;
01731     std::string out;
01732 
01733     if( !format.empty() )
01734     {
01735         if(!(mpfr_asprintf(&s, format.c_str(), mpfr_srcptr()) < 0))
01736         {
01737             out = std::string(s);
01738 
01739             mpfr_free_str(s);
01740         }
01741     }
01742 
01743     return out;
01744 }
01745 
01746 #endif
01747 
01748 inline std::string mpreal::toString(int n, int b, mp_rnd_t mode) const
01749 {
01750     // TODO: Add extended format specification (f, e, rounding mode) as it done in output operator
01751     (void)b;
01752     (void)mode;
01753 
01754 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
01755 
01756     std::ostringstream format;
01757 
01758     int digits = (n >= 0) ? n : bits2digits(mpfr_get_prec(mpfr_srcptr()));
01759     
01760     format << "%." << digits << "RNg";
01761 
01762     return toString(format.str());
01763 
01764 #else
01765 
01766     char *s, *ns = NULL; 
01767     size_t slen, nslen;
01768     mp_exp_t exp;
01769     std::string out;
01770 
01771     if(mpfr_inf_p(mp))
01772     { 
01773         if(mpfr_sgn(mp)>0) return "+Inf";
01774         else               return "-Inf";
01775     }
01776 
01777     if(mpfr_zero_p(mp)) return "0";
01778     if(mpfr_nan_p(mp))  return "NaN";
01779 
01780     s  = mpfr_get_str(NULL, &exp, b, 0, mp, mode);
01781     ns = mpfr_get_str(NULL, &exp, b, (std::max)(0,n), mp, mode);
01782 
01783     if(s!=NULL && ns!=NULL)
01784     {
01785         slen  = strlen(s);
01786         nslen = strlen(ns);
01787         if(nslen<=slen) 
01788         {
01789             mpfr_free_str(s);
01790             s = ns;
01791             slen = nslen;
01792         }
01793         else {
01794             mpfr_free_str(ns);
01795         }
01796 
01797         // Make human eye-friendly formatting if possible
01798         if (exp>0 && static_cast<size_t>(exp)<slen)
01799         {
01800             if(s[0]=='-')
01801             {
01802                 // Remove zeros starting from right end
01803                 char* ptr = s+slen-1;
01804                 while (*ptr=='0' && ptr>s+exp) ptr--; 
01805 
01806                 if(ptr==s+exp) out = std::string(s,exp+1);
01807                 else           out = std::string(s,exp+1)+'.'+std::string(s+exp+1,ptr-(s+exp+1)+1);
01808 
01809                 //out = string(s,exp+1)+'.'+string(s+exp+1);
01810             }
01811             else
01812             {
01813                 // Remove zeros starting from right end
01814                 char* ptr = s+slen-1;
01815                 while (*ptr=='0' && ptr>s+exp-1) ptr--; 
01816 
01817                 if(ptr==s+exp-1) out = std::string(s,exp);
01818                 else             out = std::string(s,exp)+'.'+std::string(s+exp,ptr-(s+exp)+1);
01819 
01820                 //out = string(s,exp)+'.'+string(s+exp);
01821             }
01822 
01823         }else{ // exp<0 || exp>slen
01824             if(s[0]=='-')
01825             {
01826                 // Remove zeros starting from right end
01827                 char* ptr = s+slen-1;
01828                 while (*ptr=='0' && ptr>s+1) ptr--; 
01829 
01830                 if(ptr==s+1) out = std::string(s,2);
01831                 else         out = std::string(s,2)+'.'+std::string(s+2,ptr-(s+2)+1);
01832 
01833                 //out = string(s,2)+'.'+string(s+2);
01834             }
01835             else
01836             {
01837                 // Remove zeros starting from right end
01838                 char* ptr = s+slen-1;
01839                 while (*ptr=='0' && ptr>s) ptr--; 
01840 
01841                 if(ptr==s) out = std::string(s,1);
01842                 else       out = std::string(s,1)+'.'+std::string(s+1,ptr-(s+1)+1);
01843 
01844                 //out = string(s,1)+'.'+string(s+1);
01845             }
01846 
01847             // Make final string
01848             if(--exp)
01849             {
01850                 if(exp>0) out += "e+"+mpfr::toString<mp_exp_t>(exp,std::dec);
01851                 else       out += "e"+mpfr::toString<mp_exp_t>(exp,std::dec);
01852             }
01853         }
01854 
01855         mpfr_free_str(s);
01856         return out;
01857     }else{
01858         return "conversion error!";
01859     }
01860 #endif
01861 }
01862 
01863 
01865 // I/O
01866 inline std::ostream& mpreal::output(std::ostream& os) const 
01867 {
01868     std::ostringstream format;
01869     const std::ios::fmtflags flags = os.flags();
01870 
01871     format << ((flags & std::ios::showpos) ? "%+" : "%");
01872     if (os.precision() >= 0)
01873         format << '.' << os.precision() << "R*"
01874                << ((flags & std::ios::floatfield) == std::ios::fixed ? 'f' :
01875                    (flags & std::ios::floatfield) == std::ios::scientific ? 'e' :
01876                    'g');
01877     else
01878         format << "R*e";
01879 
01880     char *s = NULL;
01881     if(!(mpfr_asprintf(&s, format.str().c_str(),
01882                         mpfr::mpreal::get_default_rnd(),
01883                         mpfr_srcptr())
01884         < 0))
01885     {
01886         os << std::string(s);
01887         mpfr_free_str(s);
01888     }
01889     return os;
01890 }
01891 
01892 inline std::ostream& operator<<(std::ostream& os, const mpreal& v)
01893 {
01894     return v.output(os);
01895 }
01896 
01897 inline std::istream& operator>>(std::istream &is, mpreal& v)
01898 {
01899     // TODO: use cout::hexfloat and other flags to setup base
01900     std::string tmp;
01901     is >> tmp;
01902     mpfr_set_str(v.mpfr_ptr(), tmp.c_str(), 10, mpreal::get_default_rnd());
01903     return is;
01904 }
01905 
01907 //     Bits - decimal digits relation
01908 //        bits   = ceil(digits*log[2](10))
01909 //        digits = floor(bits*log[10](2))
01910 
01911 inline mp_prec_t digits2bits(int d)
01912 {
01913     const double LOG2_10 = 3.3219280948873624;
01914 
01915     return mp_prec_t(std::ceil( d * LOG2_10 ));
01916 }
01917 
01918 inline int bits2digits(mp_prec_t b)
01919 {
01920     const double LOG10_2 = 0.30102999566398119;
01921 
01922     return int(std::floor( b * LOG10_2 ));
01923 }
01924 
01926 // Set/Get number properties
01927 inline int sgn(const mpreal& op)
01928 {
01929     int r = mpfr_signbit(op.mpfr_srcptr());
01930     return (r > 0? -1 : 1);
01931 }
01932 
01933 inline mpreal& mpreal::setSign(int sign, mp_rnd_t RoundingMode)
01934 {
01935     mpfr_setsign(mpfr_ptr(), mpfr_srcptr(), (sign < 0 ? 1 : 0), RoundingMode);
01936     MPREAL_MSVC_DEBUGVIEW_CODE;
01937     return *this;
01938 }
01939 
01940 inline int mpreal::getPrecision() const
01941 {
01942     return int(mpfr_get_prec(mpfr_srcptr()));
01943 }
01944 
01945 inline mpreal& mpreal::setPrecision(int Precision, mp_rnd_t RoundingMode)
01946 {
01947     mpfr_prec_round(mpfr_ptr(), Precision, RoundingMode);
01948     MPREAL_MSVC_DEBUGVIEW_CODE;
01949     return *this;
01950 }
01951 
01952 inline mpreal& mpreal::setInf(int sign) 
01953 { 
01954     mpfr_set_inf(mpfr_ptr(), sign);
01955     MPREAL_MSVC_DEBUGVIEW_CODE;
01956     return *this;
01957 }    
01958 
01959 inline mpreal& mpreal::setNan() 
01960 {
01961     mpfr_set_nan(mpfr_ptr());
01962     MPREAL_MSVC_DEBUGVIEW_CODE;
01963     return *this;
01964 }
01965 
01966 inline mpreal&    mpreal::setZero(int sign)
01967 {
01968 
01969 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
01970     mpfr_set_zero(mpfr_ptr(), sign);
01971 #else
01972     mpfr_set_si(mpfr_ptr(), 0, (mpfr_get_default_rounding_mode)());
01973     setSign(sign);
01974 #endif 
01975 
01976     MPREAL_MSVC_DEBUGVIEW_CODE;
01977     return *this;
01978 }
01979 
01980 inline mp_prec_t mpreal::get_prec() const
01981 {
01982     return mpfr_get_prec(mpfr_srcptr());
01983 }
01984 
01985 inline void mpreal::set_prec(mp_prec_t prec, mp_rnd_t rnd_mode)
01986 {
01987     mpfr_prec_round(mpfr_ptr(),prec,rnd_mode);
01988     MPREAL_MSVC_DEBUGVIEW_CODE;
01989 }
01990 
01991 inline mp_exp_t mpreal::get_exp ()
01992 {
01993     return mpfr_get_exp(mpfr_srcptr());
01994 }
01995 
01996 inline int mpreal::set_exp (mp_exp_t e)
01997 {
01998     int x = mpfr_set_exp(mpfr_ptr(), e);
01999     MPREAL_MSVC_DEBUGVIEW_CODE;
02000     return x;
02001 }
02002 
02003 inline const mpreal frexp(const mpreal& v, mp_exp_t* exp)
02004 {
02005     mpreal x(v);
02006     *exp = x.get_exp();
02007     x.set_exp(0);
02008     return x;
02009 }
02010 
02011 inline const mpreal ldexp(const mpreal& v, mp_exp_t exp)
02012 {
02013     mpreal x(v);
02014 
02015     // rounding is not important since we just increasing the exponent
02016     mpfr_mul_2si(x.mpfr_ptr(), x.mpfr_srcptr(), exp, mpreal::get_default_rnd()); 
02017     return x;
02018 }
02019 
02020 inline mpreal machine_epsilon(mp_prec_t prec)
02021 {
02022     /* the smallest eps such that 1 + eps != 1 */
02023     return machine_epsilon(mpreal(1, prec));
02024 }
02025 
02026 inline mpreal machine_epsilon(const mpreal& x)
02027 {    
02028     /* the smallest eps such that x + eps != x */
02029     if( x < 0)
02030     {
02031         return nextabove(-x) + x;
02032     }else{
02033         return nextabove( x) - x;
02034     }
02035 }
02036 
02037 // minval is 'safe' meaning 1 / minval does not overflow
02038 inline mpreal minval(mp_prec_t prec)
02039 {
02040     /* min = 1/2 * 2^emin = 2^(emin - 1) */
02041     return mpreal(1, prec) << mpreal::get_emin()-1;
02042 }
02043 
02044 // maxval is 'safe' meaning 1 / maxval does not underflow
02045 inline mpreal maxval(mp_prec_t prec)
02046 {
02047     /* max = (1 - eps) * 2^emax, eps is machine epsilon */
02048     return (mpreal(1, prec) - machine_epsilon(prec)) << mpreal::get_emax(); 
02049 }
02050 
02051 inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps)
02052 {
02053     return abs(a - b) <= machine_epsilon((max)(abs(a), abs(b))) * maxUlps;
02054 }
02055 
02056 inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps)
02057 {
02058     return abs(a - b) <= eps;
02059 }
02060 
02061 inline bool isEqualFuzzy(const mpreal& a, const mpreal& b)
02062 {
02063     return isEqualFuzzy(a, b, machine_epsilon((max)(1, (min)(abs(a), abs(b)))));
02064 }
02065 
02066 inline const mpreal modf(const mpreal& v, mpreal& n)
02067 {
02068     mpreal f(v);
02069 
02070     // rounding is not important since we are using the same number
02071     mpfr_frac (f.mpfr_ptr(),f.mpfr_srcptr(),mpreal::get_default_rnd());    
02072     mpfr_trunc(n.mpfr_ptr(),v.mpfr_srcptr());
02073     return f;
02074 }
02075 
02076 inline int mpreal::check_range (int t, mp_rnd_t rnd_mode)
02077 {
02078     return mpfr_check_range(mpfr_ptr(),t,rnd_mode);
02079 }
02080 
02081 inline int mpreal::subnormalize (int t,mp_rnd_t rnd_mode)
02082 {
02083     int r = mpfr_subnormalize(mpfr_ptr(),t,rnd_mode);
02084     MPREAL_MSVC_DEBUGVIEW_CODE;
02085     return r;
02086 }
02087 
02088 inline mp_exp_t mpreal::get_emin (void)
02089 {
02090     return mpfr_get_emin();
02091 }
02092 
02093 inline int mpreal::set_emin (mp_exp_t exp)
02094 {
02095     return mpfr_set_emin(exp);
02096 }
02097 
02098 inline mp_exp_t mpreal::get_emax (void)
02099 {
02100     return mpfr_get_emax();
02101 }
02102 
02103 inline int mpreal::set_emax (mp_exp_t exp)
02104 {
02105     return mpfr_set_emax(exp);
02106 }
02107 
02108 inline mp_exp_t mpreal::get_emin_min (void)
02109 {
02110     return mpfr_get_emin_min();
02111 }
02112 
02113 inline mp_exp_t mpreal::get_emin_max (void)
02114 {
02115     return mpfr_get_emin_max();
02116 }
02117 
02118 inline mp_exp_t mpreal::get_emax_min (void)
02119 {
02120     return mpfr_get_emax_min();
02121 }
02122 
02123 inline mp_exp_t mpreal::get_emax_max (void)
02124 {
02125     return mpfr_get_emax_max();
02126 }
02127 
02129 // Mathematical Functions
02131 #define MPREAL_UNARY_MATH_FUNCTION_BODY(f)                    \
02132         mpreal y(0, mpfr_get_prec(x.mpfr_srcptr()));          \
02133         mpfr_##f(y.mpfr_ptr(), x.mpfr_srcptr(), r);           \
02134         return y; 
02135 
02136 inline const mpreal sqr  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd())
02137 {   MPREAL_UNARY_MATH_FUNCTION_BODY(sqr );    }
02138 
02139 inline const mpreal sqrt (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd())
02140 {   MPREAL_UNARY_MATH_FUNCTION_BODY(sqrt);    }
02141 
02142 inline const mpreal sqrt(const unsigned long int x, mp_rnd_t r)
02143 {
02144     mpreal y;
02145     mpfr_sqrt_ui(y.mpfr_ptr(), x, r);
02146     return y;
02147 }
02148 
02149 inline const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode)
02150 {
02151     return sqrt(static_cast<unsigned long int>(v),rnd_mode);
02152 }
02153 
02154 inline const mpreal sqrt(const long int v, mp_rnd_t rnd_mode)
02155 {
02156     if (v>=0)   return sqrt(static_cast<unsigned long int>(v),rnd_mode);
02157     else        return mpreal().setNan(); // NaN  
02158 }
02159 
02160 inline const mpreal sqrt(const int v, mp_rnd_t rnd_mode)
02161 {
02162     if (v>=0)   return sqrt(static_cast<unsigned long int>(v),rnd_mode);
02163     else        return mpreal().setNan(); // NaN
02164 }
02165 
02166 inline const mpreal root(const mpreal& x, unsigned long int k, mp_rnd_t r = mpreal::get_default_rnd())
02167 {
02168     mpreal y(0, mpfr_get_prec(x.mpfr_srcptr())); 
02169     mpfr_root(y.mpfr_ptr(), x.mpfr_srcptr(), k, r);  
02170     return y; 
02171 }
02172 
02173 inline const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t r = mpreal::get_default_rnd())
02174 {
02175     mpreal y(0, mpfr_get_prec(a.mpfr_srcptr()));
02176     mpfr_dim(y.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), r);
02177     return y;
02178 }
02179 
02180 inline int cmpabs(const mpreal& a,const mpreal& b)
02181 {
02182     return mpfr_cmpabs(a.mpfr_ptr(), b.mpfr_srcptr());
02183 }
02184 
02185 inline int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02186 {
02187     return mpfr_sin_cos(s.mpfr_ptr(), c.mpfr_ptr(), v.mpfr_srcptr(), rnd_mode);
02188 }
02189 
02190 inline const mpreal sqrt  (const long double v, mp_rnd_t rnd_mode)    {   return sqrt(mpreal(v),rnd_mode);    }
02191 inline const mpreal sqrt  (const double v, mp_rnd_t rnd_mode)         {   return sqrt(mpreal(v),rnd_mode);    }
02192 
02193 inline const mpreal cbrt  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(cbrt );    }
02194 inline const mpreal fabs  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(abs  );    }
02195 inline const mpreal abs   (const mpreal& x, mp_rnd_t r)                             {   MPREAL_UNARY_MATH_FUNCTION_BODY(abs  );    }
02196 inline const mpreal log   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(log  );    }
02197 inline const mpreal log2  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(log2 );    }
02198 inline const mpreal log10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(log10);    }
02199 inline const mpreal exp   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(exp  );    }
02200 inline const mpreal exp2  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(exp2 );    }
02201 inline const mpreal exp10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(exp10);    }
02202 inline const mpreal cos   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(cos  );    }
02203 inline const mpreal sin   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(sin  );    }
02204 inline const mpreal tan   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(tan  );    }
02205 inline const mpreal sec   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(sec  );    }
02206 inline const mpreal csc   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(csc  );    }
02207 inline const mpreal cot   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(cot  );    }
02208 inline const mpreal acos  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(acos );    }
02209 inline const mpreal asin  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(asin );    }
02210 inline const mpreal atan  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(atan );    }
02211 
02212 inline const mpreal acot  (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return atan (1/v, r);                      }
02213 inline const mpreal asec  (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return acos (1/v, r);                      }
02214 inline const mpreal acsc  (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return asin (1/v, r);                      }
02215 inline const mpreal acoth (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return atanh(1/v, r);                      }
02216 inline const mpreal asech (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return acosh(1/v, r);                      }
02217 inline const mpreal acsch (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return asinh(1/v, r);                      }
02218 
02219 inline const mpreal cosh  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(cosh );    }
02220 inline const mpreal sinh  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(sinh );    }
02221 inline const mpreal tanh  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(tanh );    }
02222 inline const mpreal sech  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(sech );    }
02223 inline const mpreal csch  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(csch );    }
02224 inline const mpreal coth  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(coth );    }
02225 inline const mpreal acosh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(acosh);    }
02226 inline const mpreal asinh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(asinh);    }
02227 inline const mpreal atanh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(atanh);    }
02228 
02229 inline const mpreal log1p   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(log1p  );    }
02230 inline const mpreal expm1   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(expm1  );    }
02231 inline const mpreal eint    (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(eint   );    }
02232 inline const mpreal gamma   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(gamma  );    }
02233 inline const mpreal lngamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(lngamma);    }
02234 inline const mpreal zeta    (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(zeta   );    }
02235 inline const mpreal erf     (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(erf    );    }
02236 inline const mpreal erfc    (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(erfc   );    }
02237 inline const mpreal besselj0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(j0     );    }
02238 inline const mpreal besselj1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(j1     );    }
02239 inline const mpreal bessely0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(y0     );    }
02240 inline const mpreal bessely1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(y1     );    }
02241 
02242 inline const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02243 {
02244     mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision()));
02245     mpfr_atan2(a.mpfr_ptr(), y.mpfr_srcptr(), x.mpfr_srcptr(), rnd_mode);
02246     return a;
02247 }
02248 
02249 inline const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02250 {
02251     mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision()));
02252     mpfr_hypot(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode);
02253     return a;
02254 }
02255 
02256 inline const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02257 {    
02258     mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision()));
02259     mpfr_remainder(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode);
02260     return a;
02261 }
02262 
02263 inline const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02264 {
02265     mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision()));
02266     mpfr_remquo(a.mpfr_ptr(),q, x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode);
02267     return a;
02268 }
02269 
02270 inline const mpreal fac_ui (unsigned long int v, mp_prec_t prec     = mpreal::get_default_prec(),
02271                                            mp_rnd_t  rnd_mode = mpreal::get_default_rnd())
02272 {
02273     mpreal x(0, prec);
02274     mpfr_fac_ui(x.mpfr_ptr(),v,rnd_mode);
02275     return x;
02276 }
02277 
02278 
02279 inline const mpreal lgamma (const mpreal& v, int *signp = 0, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02280 {
02281     mpreal x(v);
02282     int tsignp;
02283 
02284     if(signp)   mpfr_lgamma(x.mpfr_ptr(),  signp,v.mpfr_srcptr(),rnd_mode);
02285     else        mpfr_lgamma(x.mpfr_ptr(),&tsignp,v.mpfr_srcptr(),rnd_mode);
02286 
02287     return x;
02288 }
02289 
02290 
02291 inline const mpreal besseljn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd())
02292 {
02293     mpreal  y(0, x.getPrecision());
02294     mpfr_jn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r);
02295     return y;
02296 }
02297 
02298 inline const mpreal besselyn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd())
02299 {
02300     mpreal  y(0, x.getPrecision());
02301     mpfr_yn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r);
02302     return y;
02303 }
02304 
02305 inline const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02306 {
02307     mpreal a;
02308     mp_prec_t p1, p2, p3;
02309 
02310     p1 = v1.get_prec(); 
02311     p2 = v2.get_prec(); 
02312     p3 = v3.get_prec(); 
02313 
02314     a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
02315 
02316     mpfr_fma(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
02317     return a;
02318 }
02319 
02320 inline const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02321 {
02322     mpreal a;
02323     mp_prec_t p1, p2, p3;
02324 
02325     p1 = v1.get_prec(); 
02326     p2 = v2.get_prec(); 
02327     p3 = v3.get_prec(); 
02328 
02329     a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
02330 
02331     mpfr_fms(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
02332     return a;
02333 }
02334 
02335 inline const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02336 {
02337     mpreal a;
02338     mp_prec_t p1, p2;
02339 
02340     p1 = v1.get_prec(); 
02341     p2 = v2.get_prec(); 
02342 
02343     a.set_prec(p1>p2?p1:p2);
02344 
02345     mpfr_agm(a.mp, v1.mp, v2.mp, rnd_mode);
02346 
02347     return a;
02348 }
02349 
02350 inline const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02351 {
02352     mpreal x;
02353     mpfr_ptr* t;
02354     unsigned long int i;
02355 
02356     t = new mpfr_ptr[n];
02357     for (i=0;i<n;i++) t[i] = (mpfr_ptr)tab[i].mp;
02358     mpfr_sum(x.mp,t,n,rnd_mode);
02359     delete[] t;
02360     return x;
02361 }
02362 
02364 // MPFR 2.4.0 Specifics
02365 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
02366 
02367 inline int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02368 {
02369     return mpfr_sinh_cosh(s.mp,c.mp,v.mp,rnd_mode);
02370 }
02371 
02372 inline const mpreal li2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) 
02373 {   
02374     MPREAL_UNARY_MATH_FUNCTION_BODY(li2);    
02375 }
02376 
02377 inline const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02378 {
02379     /*  R = rem(X,Y) if Y != 0, returns X - n * Y where n = trunc(X/Y). */
02380     return fmod(x, y, rnd_mode);
02381 }
02382 
02383 inline const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02384 {
02385     (void)rnd_mode;
02386     
02387     /*  
02388 
02389     m = mod(x,y) if y != 0, returns x - n*y where n = floor(x/y)
02390 
02391     The following are true by convention:
02392     - mod(x,0) is x
02393     - mod(x,x) is 0
02394     - mod(x,y) for x != y and y != 0 has the same sign as y.    
02395     
02396     */
02397 
02398     if(iszero(y)) return x;
02399     if(x == y) return 0;
02400 
02401     mpreal m = x - floor(x / y) * y;
02402     
02403     m.setSign(sgn(y)); // make sure result has the same sign as Y
02404 
02405     return m;
02406 }
02407 
02408 inline const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02409 {
02410     mpreal a;
02411     mp_prec_t yp, xp;
02412 
02413     yp = y.get_prec(); 
02414     xp = x.get_prec(); 
02415 
02416     a.set_prec(yp>xp?yp:xp);
02417 
02418     mpfr_fmod(a.mp, x.mp, y.mp, rnd_mode);
02419 
02420     return a;
02421 }
02422 
02423 inline const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02424 {
02425     mpreal x(v);
02426     mpfr_rec_sqrt(x.mp,v.mp,rnd_mode);
02427     return x;
02428 }
02429 #endif //  MPFR 2.4.0 Specifics
02430 
02432 // MPFR 3.0.0 Specifics
02433 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
02434 inline const mpreal digamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(digamma);     }
02435 inline const mpreal ai      (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(ai);          }
02436 #endif // MPFR 3.0.0 Specifics
02437 
02439 // Constants
02440 inline const mpreal const_log2 (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd())
02441 {
02442     mpreal x(0, p);
02443     mpfr_const_log2(x.mpfr_ptr(), r);
02444     return x;
02445 }
02446 
02447 inline const mpreal const_pi (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd())
02448 {
02449     mpreal x(0, p);
02450     mpfr_const_pi(x.mpfr_ptr(), r);
02451     return x;
02452 }
02453 
02454 inline const mpreal const_euler (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd())
02455 {
02456     mpreal x(0, p);
02457     mpfr_const_euler(x.mpfr_ptr(), r);
02458     return x;
02459 }
02460 
02461 inline const mpreal const_catalan (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd())
02462 {
02463     mpreal x(0, p);
02464     mpfr_const_catalan(x.mpfr_ptr(), r);
02465     return x;
02466 }
02467 
02468 inline const mpreal const_infinity (int sign = 1, mp_prec_t p = mpreal::get_default_prec())
02469 {
02470     mpreal x(0, p);
02471     mpfr_set_inf(x.mpfr_ptr(), sign);
02472     return x;
02473 }
02474 
02476 // Integer Related Functions
02477 inline const mpreal ceil(const mpreal& v)
02478 {
02479     mpreal x(v);
02480     mpfr_ceil(x.mp,v.mp);
02481     return x;
02482 }
02483 
02484 inline const mpreal floor(const mpreal& v)
02485 {
02486     mpreal x(v);
02487     mpfr_floor(x.mp,v.mp);
02488     return x;
02489 }
02490 
02491 inline const mpreal round(const mpreal& v)
02492 {
02493     mpreal x(v);
02494     mpfr_round(x.mp,v.mp);
02495     return x;
02496 }
02497 
02498 inline const mpreal trunc(const mpreal& v)
02499 {
02500     mpreal x(v);
02501     mpfr_trunc(x.mp,v.mp);
02502     return x;
02503 }
02504 
02505 inline const mpreal rint       (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint      );     }
02506 inline const mpreal rint_ceil  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint_ceil );     }
02507 inline const mpreal rint_floor (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint_floor);     }
02508 inline const mpreal rint_round (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint_round);     }
02509 inline const mpreal rint_trunc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint_trunc);     }
02510 inline const mpreal frac       (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(frac      );     }
02511 
02513 // Miscellaneous Functions
02514 inline void         swap (mpreal& a, mpreal& b)            {    mpfr_swap(a.mp,b.mp);   }
02515 inline const mpreal (max)(const mpreal& x, const mpreal& y){    return (x>y?x:y);       }
02516 inline const mpreal (min)(const mpreal& x, const mpreal& y){    return (x<y?x:y);       }
02517 
02518 inline const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02519 {
02520     mpreal a;
02521     mpfr_max(a.mp,x.mp,y.mp,rnd_mode);
02522     return a;
02523 }
02524 
02525 inline const mpreal fmin(const mpreal& x, const mpreal& y,  mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02526 {
02527     mpreal a;
02528     mpfr_min(a.mp,x.mp,y.mp,rnd_mode);
02529     return a;
02530 }
02531 
02532 inline const mpreal nexttoward (const mpreal& x, const mpreal& y)
02533 {
02534     mpreal a(x);
02535     mpfr_nexttoward(a.mp,y.mp);
02536     return a;
02537 }
02538 
02539 inline const mpreal nextabove  (const mpreal& x)
02540 {
02541     mpreal a(x);
02542     mpfr_nextabove(a.mp);
02543     return a;
02544 }
02545 
02546 inline const mpreal nextbelow  (const mpreal& x)
02547 {
02548     mpreal a(x);
02549     mpfr_nextbelow(a.mp);
02550     return a;
02551 }
02552 
02553 inline const mpreal urandomb (gmp_randstate_t& state)
02554 {
02555     mpreal x;
02556     mpfr_urandomb(x.mp,state);
02557     return x;
02558 }
02559 
02560 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,1,0))
02561 // use gmp_randinit_default() to init state, gmp_randclear() to clear
02562 inline const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02563 {
02564     mpreal x;
02565     mpfr_urandom(x.mp,state,rnd_mode);
02566     return x;
02567 }
02568 
02569 inline const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02570 {
02571     mpreal x;
02572     mpfr_grandom(x.mp, NULL, state, rnd_mode);
02573     return x;
02574 }
02575 
02576 #endif 
02577 
02578 #if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2))
02579 inline const mpreal random2 (mp_size_t size, mp_exp_t exp)
02580 {
02581     mpreal x;
02582     mpfr_random2(x.mp,size,exp);
02583     return x;
02584 }
02585 #endif
02586 
02587 // Uniformly distributed random number generation
02588 // a = random(seed); <- initialization & first random number generation
02589 // a = random();     <- next random numbers generation
02590 // seed != 0
02591 inline const mpreal random(unsigned int seed = 0)
02592 {
02593 
02594 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
02595     static gmp_randstate_t state;
02596     static bool isFirstTime = true;
02597 
02598     if(isFirstTime)
02599     {
02600         gmp_randinit_default(state);
02601         gmp_randseed_ui(state,0);
02602         isFirstTime = false;
02603     }
02604 
02605     if(seed != 0)    gmp_randseed_ui(state,seed);
02606 
02607     return mpfr::urandom(state);
02608 #else
02609     if(seed != 0)    std::srand(seed);
02610     return mpfr::mpreal(std::rand()/(double)RAND_MAX);
02611 #endif
02612 
02613 }
02614 
02615 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
02616 inline const mpreal grandom(unsigned int seed = 0)
02617 {
02618     static gmp_randstate_t state;
02619     static bool isFirstTime = true;
02620 
02621     if(isFirstTime)
02622     {
02623         gmp_randinit_default(state);
02624         gmp_randseed_ui(state,0);
02625         isFirstTime = false;
02626     }
02627 
02628     if(seed != 0) gmp_randseed_ui(state,seed);
02629 
02630     return mpfr::grandom(state);
02631 }
02632 #endif
02633 
02635 // Set/Get global properties
02636 inline void mpreal::set_default_prec(mp_prec_t prec)
02637 { 
02638     mpfr_set_default_prec(prec); 
02639 }
02640 
02641 inline void mpreal::set_default_rnd(mp_rnd_t rnd_mode)
02642 { 
02643     mpfr_set_default_rounding_mode(rnd_mode); 
02644 }
02645 
02646 inline bool mpreal::fits_in_bits(double x, int n)
02647 {   
02648     int i;
02649     double t;
02650     return IsInf(x) || (std::modf ( std::ldexp ( std::frexp ( x, &i ), n ), &t ) == 0.0);
02651 }
02652 
02653 inline const mpreal pow(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02654 {
02655     mpreal x(a);
02656     mpfr_pow(x.mp,x.mp,b.mp,rnd_mode);
02657     return x;
02658 }
02659 
02660 inline const mpreal pow(const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02661 {
02662     mpreal x(a);
02663     mpfr_pow_z(x.mp,x.mp,b,rnd_mode);
02664     return x;
02665 }
02666 
02667 inline const mpreal pow(const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02668 {
02669     mpreal x(a);
02670     mpfr_pow_ui(x.mp,x.mp,b,rnd_mode);
02671     return x;
02672 }
02673 
02674 inline const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode)
02675 {
02676     return pow(a,static_cast<unsigned long int>(b),rnd_mode);
02677 }
02678 
02679 inline const mpreal pow(const mpreal& a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02680 {
02681     mpreal x(a);
02682     mpfr_pow_si(x.mp,x.mp,b,rnd_mode);
02683     return x;
02684 }
02685 
02686 inline const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode)
02687 {
02688     return pow(a,static_cast<long int>(b),rnd_mode);
02689 }
02690 
02691 inline const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode)
02692 {
02693     return pow(a,mpreal(b),rnd_mode);
02694 }
02695 
02696 inline const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode)
02697 {
02698     return pow(a,mpreal(b),rnd_mode);
02699 }
02700 
02701 inline const mpreal pow(const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
02702 {
02703     mpreal x(a);
02704     mpfr_ui_pow(x.mp,a,b.mp,rnd_mode);
02705     return x;
02706 }
02707 
02708 inline const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode)
02709 {
02710     return pow(static_cast<unsigned long int>(a),b,rnd_mode);
02711 }
02712 
02713 inline const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode)
02714 {
02715     if (a>=0)     return pow(static_cast<unsigned long int>(a),b,rnd_mode);
02716     else          return pow(mpreal(a),b,rnd_mode);
02717 }
02718 
02719 inline const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode)
02720 {
02721     if (a>=0)     return pow(static_cast<unsigned long int>(a),b,rnd_mode);
02722     else          return pow(mpreal(a),b,rnd_mode);
02723 }
02724 
02725 inline const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode)
02726 {
02727     return pow(mpreal(a),b,rnd_mode);
02728 }
02729 
02730 inline const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode)
02731 {
02732     return pow(mpreal(a),b,rnd_mode);
02733 }
02734 
02735 // pow unsigned long int
02736 inline const mpreal pow(const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode)
02737 {
02738     mpreal x(a);
02739     mpfr_ui_pow_ui(x.mp,a,b,rnd_mode);
02740     return x;
02741 }
02742 
02743 inline const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode)
02744 {
02745     return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02746 }
02747 
02748 inline const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode)
02749 {
02750     if(b>0)    return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02751     else       return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
02752 }
02753 
02754 inline const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode)
02755 {
02756     if(b>0)    return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02757     else       return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
02758 }
02759 
02760 inline const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode)
02761 {
02762     return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
02763 }
02764 
02765 inline const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode)
02766 {
02767     return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
02768 }
02769 
02770 // pow unsigned int
02771 inline const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode)
02772 {
02773     return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
02774 }
02775 
02776 inline const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode)
02777 {
02778     return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02779 }
02780 
02781 inline const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode)
02782 {
02783     if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02784     else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02785 }
02786 
02787 inline const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode)
02788 {
02789     if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02790     else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02791 }
02792 
02793 inline const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode)
02794 {
02795     return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02796 }
02797 
02798 inline const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode)
02799 {
02800     return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02801 }
02802 
02803 // pow long int
02804 inline const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode)
02805 {
02806     if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
02807     else     return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
02808 }
02809 
02810 inline const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode)
02811 {
02812     if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode);  //mpfr_ui_pow_ui
02813     else     return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
02814 }
02815 
02816 inline const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode)
02817 {
02818     if (a>0)
02819     {
02820         if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02821         else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02822     }else{
02823         return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
02824     }
02825 }
02826 
02827 inline const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode)
02828 {
02829     if (a>0)
02830     {
02831         if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02832         else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02833     }else{
02834         return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
02835     }
02836 }
02837 
02838 inline const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode)
02839 {
02840     if (a>=0)   return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02841     else        return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
02842 }
02843 
02844 inline const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode)
02845 {
02846     if (a>=0)   return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02847     else        return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
02848 }
02849 
02850 // pow int
02851 inline const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode)
02852 {
02853     if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
02854     else     return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
02855 }
02856 
02857 inline const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode)
02858 {
02859     if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode);  //mpfr_ui_pow_ui
02860     else     return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
02861 }
02862 
02863 inline const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode)
02864 {
02865     if (a>0)
02866     {
02867         if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02868         else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02869     }else{
02870         return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
02871     }
02872 }
02873 
02874 inline const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode)
02875 {
02876     if (a>0)
02877     {
02878         if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
02879         else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02880     }else{
02881         return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
02882     }
02883 }
02884 
02885 inline const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode)
02886 {
02887     if (a>=0)   return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02888     else        return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
02889 }
02890 
02891 inline const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode)
02892 {
02893     if (a>=0)   return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
02894     else        return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
02895 }
02896 
02897 // pow long double 
02898 inline const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode)
02899 {
02900     return pow(mpreal(a),mpreal(b),rnd_mode);
02901 }
02902 
02903 inline const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode)
02904 {
02905     return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
02906 }
02907 
02908 inline const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode)
02909 {
02910     return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
02911 }
02912 
02913 inline const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode)
02914 {
02915     return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
02916 }
02917 
02918 inline const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode)
02919 {
02920     return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
02921 }
02922 
02923 inline const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode)
02924 {
02925     return pow(mpreal(a),mpreal(b),rnd_mode);
02926 }
02927 
02928 inline const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode)
02929 {
02930     return pow(mpreal(a),b,rnd_mode); // mpfr_pow_ui
02931 }
02932 
02933 inline const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode)
02934 {
02935     return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); // mpfr_pow_ui
02936 }
02937 
02938 inline const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode)
02939 {
02940     return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
02941 }
02942 
02943 inline const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode)
02944 {
02945     return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
02946 }
02947 } // End of mpfr namespace
02948 
02949 // Explicit specialization of std::swap for mpreal numbers
02950 // Thus standard algorithms will use efficient version of swap (due to Koenig lookup)
02951 // Non-throwing swap C++ idiom: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-throwing_swap
02952 namespace std
02953 {
02954   // we are allowed to extend namespace std with specializations only
02955     template <>
02956     inline void swap(mpfr::mpreal& x, mpfr::mpreal& y) 
02957     { 
02958         return mpfr::swap(x, y); 
02959     }
02960 
02961     template<>
02962     class numeric_limits<mpfr::mpreal>
02963     {
02964     public:
02965         static const bool is_specialized    = true;
02966         static const bool is_signed         = true;
02967         static const bool is_integer        = false;
02968         static const bool is_exact          = false;
02969         static const int  radix             = 2;    
02970 
02971         static const bool has_infinity      = true;
02972         static const bool has_quiet_NaN     = true;
02973         static const bool has_signaling_NaN = true;
02974 
02975         static const bool is_iec559         = true;        // = IEEE 754
02976         static const bool is_bounded        = true;
02977         static const bool is_modulo         = false;
02978         static const bool traps             = true;
02979         static const bool tinyness_before   = true;
02980 
02981         static const float_denorm_style has_denorm  = denorm_absent;
02982 
02983         inline static mpfr::mpreal (min)    (mp_prec_t precision = mpfr::mpreal::get_default_prec()) {  return  mpfr::minval(precision);  }
02984         inline static mpfr::mpreal (max)    (mp_prec_t precision = mpfr::mpreal::get_default_prec()) {  return  mpfr::maxval(precision);  }
02985         inline static mpfr::mpreal lowest   (mp_prec_t precision = mpfr::mpreal::get_default_prec()) {  return -mpfr::maxval(precision);  }
02986 
02987         // Returns smallest eps such that 1 + eps != 1 (classic machine epsilon)
02988         inline static mpfr::mpreal epsilon(mp_prec_t precision = mpfr::mpreal::get_default_prec()) {  return  mpfr::machine_epsilon(precision); }
02989     
02990         // Returns smallest eps such that x + eps != x (relative machine epsilon)
02991         inline static mpfr::mpreal epsilon(const mpfr::mpreal& x) {  return mpfr::machine_epsilon(x);  }
02992 
02993         inline static mpfr::mpreal round_error(mp_prec_t precision = mpfr::mpreal::get_default_prec())
02994         {
02995             mp_rnd_t r = mpfr::mpreal::get_default_rnd();
02996 
02997             if(r == GMP_RNDN)  return mpfr::mpreal(0.5, precision); 
02998             else               return mpfr::mpreal(1.0, precision);    
02999         }
03000 
03001         inline static const mpfr::mpreal infinity()         { return mpfr::const_infinity();     }
03002         inline static const mpfr::mpreal quiet_NaN()        { return mpfr::mpreal().setNan();    }
03003         inline static const mpfr::mpreal signaling_NaN()    { return mpfr::mpreal().setNan();    }
03004         inline static const mpfr::mpreal denorm_min()       { return (min)();                    }
03005 
03006         // Please note, exponent range is not fixed in MPFR
03007         static const int min_exponent = MPFR_EMIN_DEFAULT;
03008         static const int max_exponent = MPFR_EMAX_DEFAULT;
03009         MPREAL_PERMISSIVE_EXPR static const int min_exponent10 = (int) (MPFR_EMIN_DEFAULT * 0.3010299956639811); 
03010         MPREAL_PERMISSIVE_EXPR static const int max_exponent10 = (int) (MPFR_EMAX_DEFAULT * 0.3010299956639811); 
03011 
03012 #ifdef MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS
03013 
03014         // Following members should be constant according to standard, but they can be variable in MPFR
03015         // So we define them as functions here. 
03016         //
03017         // This is preferable way for std::numeric_limits<mpfr::mpreal> specialization.
03018         // But it is incompatible with standard std::numeric_limits and might not work with other libraries, e.g. boost. 
03019         // See below for compatible implementation. 
03020         inline static float_round_style round_style()
03021         {
03022             mp_rnd_t r = mpfr::mpreal::get_default_rnd();
03023 
03024             switch (r)
03025             {
03026             case GMP_RNDN: return round_to_nearest;
03027             case GMP_RNDZ: return round_toward_zero; 
03028             case GMP_RNDU: return round_toward_infinity; 
03029             case GMP_RNDD: return round_toward_neg_infinity; 
03030             default: return round_indeterminate;
03031             }
03032         }
03033 
03034         inline static int digits()                        {    return int(mpfr::mpreal::get_default_prec());    }
03035         inline static int digits(const mpfr::mpreal& x)   {    return x.getPrecision();                         }
03036 
03037         inline static int digits10(mp_prec_t precision = mpfr::mpreal::get_default_prec())
03038         {
03039             return mpfr::bits2digits(precision);
03040         }
03041 
03042         inline static int digits10(const mpfr::mpreal& x)
03043         {
03044             return mpfr::bits2digits(x.getPrecision());
03045         }
03046 
03047         inline static int max_digits10(mp_prec_t precision = mpfr::mpreal::get_default_prec())
03048         {
03049             return digits10(precision);
03050         }
03051 #else
03052         // Digits and round_style are NOT constants when it comes to mpreal.
03053         // If possible, please use functions digits() and round_style() defined above.
03054         //
03055         // These (default) values are preserved for compatibility with existing libraries, e.g. boost.
03056         // Change them accordingly to your application. 
03057         //
03058         // For example, if you use 256 bits of precision uniformly in your program, then:
03059         // digits       = 256
03060         // digits10     = 77 
03061         // max_digits10 = 78
03062         // 
03063         // Approximate formula for decimal digits is: digits10 = floor(log10(2) * digits). See bits2digits() for more details.
03064 
03065         static const std::float_round_style round_style = round_to_nearest;
03066         static const int digits       = 53;
03067         static const int digits10     = 15;
03068         static const int max_digits10 = 16;
03069 #endif
03070     };
03071 
03072 }
03073 
03074 #endif /* __MPREAL_H__ */


shape_reconstruction
Author(s): Roberto Martín-Martín
autogenerated on Sat Jun 8 2019 18:33:22