Home | History | Annotate | Download | only in mpreal
      1 /*
      2     MPFR C++: Multi-precision floating point number class for C++.
      3     Based on MPFR library:    http://mpfr.org
      4 
      5     Project homepage:    http://www.holoborodko.com/pavel/mpfr
      6     Contact e-mail:      pavel (at) holoborodko.com
      7 
      8     Copyright (c) 2008-2014 Pavel Holoborodko
      9 
     10     Contributors:
     11     Dmitriy Gubanov, Konstantin Holoborodko, Brian Gladman,
     12     Helmut Jarausch, Fokko Beekhof, Ulrich Mutze, Heinz van Saanen,
     13     Pere Constans, Peter van Hoof, Gael Guennebaud, Tsai Chia Cheng,
     14     Alexei Zubanov, Jauhien Piatlicki, Victor Berger, John Westwood,
     15     Petr Aleksandrov, Orion Poplawski, Charles Karney.
     16 
     17     Licensing:
     18     (A) MPFR C++ is under GNU General Public License ("GPL").
     19 
     20     (B) Non-free licenses may also be purchased from the author, for users who
     21         do not want their programs protected by the GPL.
     22 
     23         The non-free licenses are for users that wish to use MPFR C++ in
     24         their products but are unwilling to release their software
     25         under the GPL (which would require them to release source code
     26         and allow free redistribution).
     27 
     28         Such users can purchase an unlimited-use license from the author.
     29         Contact us for more details.
     30 
     31     GNU General Public License ("GPL") copyright permissions statement:
     32     **************************************************************************
     33     This program is free software: you can redistribute it and/or modify
     34     it under the terms of the GNU General Public License as published by
     35     the Free Software Foundation, either version 3 of the License, or
     36     (at your option) any later version.
     37 
     38     This program is distributed in the hope that it will be useful,
     39     but WITHOUT ANY WARRANTY; without even the implied warranty of
     40     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     41     GNU General Public License for more details.
     42 
     43     You should have received a copy of the GNU General Public License
     44     along with this program.  If not, see <http://www.gnu.org/licenses/>.
     45 */
     46 
     47 #ifndef __MPREAL_H__
     48 #define __MPREAL_H__
     49 
     50 #include <string>
     51 #include <iostream>
     52 #include <sstream>
     53 #include <stdexcept>
     54 #include <cfloat>
     55 #include <cmath>
     56 #include <cstring>
     57 #include <limits>
     58 
     59 // Options
     60 #define MPREAL_HAVE_INT64_SUPPORT               // Enable int64_t support if possible. Available only for MSVC 2010 & GCC.
     61 #define MPREAL_HAVE_MSVC_DEBUGVIEW              // Enable Debugger Visualizer for "Debug" builds in MSVC.
     62 #define MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS  // Enable extended std::numeric_limits<mpfr::mpreal> specialization.
     63                                                 // Meaning that "digits", "round_style" and similar members are defined as functions, not constants.
     64                                                 // See std::numeric_limits<mpfr::mpreal> at the end of the file for more information.
     65 
     66 // Library version
     67 #define MPREAL_VERSION_MAJOR 3
     68 #define MPREAL_VERSION_MINOR 5
     69 #define MPREAL_VERSION_PATCHLEVEL 9
     70 #define MPREAL_VERSION_STRING "3.5.9"
     71 
     72 // Detect compiler using signatures from http://predef.sourceforge.net/
     73 #if defined(__GNUC__) && defined(__INTEL_COMPILER)
     74     #define IsInf(x) isinf(x)                   // Intel ICC compiler on Linux
     75 
     76 #elif defined(_MSC_VER)                         // Microsoft Visual C++
     77     #define IsInf(x) (!_finite(x))
     78 
     79 #else
     80     #define IsInf(x) std::isinf(x)              // GNU C/C++ (and/or other compilers), just hope for C99 conformance
     81 #endif
     82 
     83 // A Clang feature extension to determine compiler features.
     84 #ifndef __has_feature
     85     #define __has_feature(x) 0
     86 #endif
     87 
     88 // Detect support for r-value references (move semantic). Borrowed from Eigen.
     89 #if (__has_feature(cxx_rvalue_references) || \
     90        defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \
     91       (defined(_MSC_VER) && _MSC_VER >= 1600))
     92 
     93     #define MPREAL_HAVE_MOVE_SUPPORT
     94 
     95     // Use fields in mpfr_t structure to check if it was initialized / set dummy initialization
     96     #define mpfr_is_initialized(x)      (0 != (x)->_mpfr_d)
     97     #define mpfr_set_uninitialized(x)   ((x)->_mpfr_d = 0 )
     98 #endif
     99 
    100 // Detect support for explicit converters.
    101 #if (__has_feature(cxx_explicit_conversions) || \
    102        defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \
    103       (defined(_MSC_VER) && _MSC_VER >= 1800))
    104 
    105     #define MPREAL_HAVE_EXPLICIT_CONVERTERS
    106 #endif
    107 
    108 // Detect available 64-bit capabilities
    109 #if defined(MPREAL_HAVE_INT64_SUPPORT)
    110 
    111     #define MPFR_USE_INTMAX_T                   // Should be defined before mpfr.h
    112 
    113     #if defined(_MSC_VER)                       // MSVC + Windows
    114         #if (_MSC_VER >= 1600)
    115             #include <stdint.h>                 // <stdint.h> is available only in msvc2010!
    116 
    117         #else                                   // MPFR relies on intmax_t which is available only in msvc2010
    118             #undef MPREAL_HAVE_INT64_SUPPORT    // Besides, MPFR & MPIR have to be compiled with msvc2010
    119             #undef MPFR_USE_INTMAX_T            // Since we cannot detect this, disable x64 by default
    120                                                 // Someone should change this manually if needed.
    121         #endif
    122 
    123     #elif defined (__GNUC__) && defined(__linux__)
    124         #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) || defined (__PPC64__)
    125             #undef MPREAL_HAVE_INT64_SUPPORT    // Remove all shaman dances for x64 builds since
    126             #undef MPFR_USE_INTMAX_T            // GCC already supports x64 as of "long int" is 64-bit integer, nothing left to do
    127         #else
    128             #include <stdint.h>                 // use int64_t, uint64_t otherwise
    129         #endif
    130 
    131     #else
    132         #include <stdint.h>                     // rely on int64_t, uint64_t in all other cases, Mac OSX, etc.
    133     #endif
    134 
    135 #endif
    136 
    137 #if defined(MPREAL_HAVE_MSVC_DEBUGVIEW) && defined(_MSC_VER) && defined(_DEBUG)
    138     #define MPREAL_MSVC_DEBUGVIEW_CODE     DebugView = toString();
    139     #define MPREAL_MSVC_DEBUGVIEW_DATA     std::string DebugView;
    140 #else
    141     #define MPREAL_MSVC_DEBUGVIEW_CODE
    142     #define MPREAL_MSVC_DEBUGVIEW_DATA
    143 #endif
    144 
    145 #include <mpfr.h>
    146 
    147 #if (MPFR_VERSION < MPFR_VERSION_NUM(3,0,0))
    148     #include <cstdlib>                          // Needed for random()
    149 #endif
    150 
    151 // Less important options
    152 #define MPREAL_DOUBLE_BITS_OVERFLOW -1          // Triggers overflow exception during conversion to double if mpreal
    153                                                 // cannot fit in MPREAL_DOUBLE_BITS_OVERFLOW bits
    154                                                 // = -1 disables overflow checks (default)
    155 #if defined(__GNUC__)
    156   #define MPREAL_PERMISSIVE_EXPR __extension__
    157 #else
    158   #define MPREAL_PERMISSIVE_EXPR
    159 #endif
    160 
    161 namespace mpfr {
    162 
    163 class mpreal {
    164 private:
    165     mpfr_t mp;
    166 
    167 public:
    168 
    169     // Get default rounding mode & precision
    170     inline static mp_rnd_t   get_default_rnd()    {    return (mp_rnd_t)(mpfr_get_default_rounding_mode());       }
    171     inline static mp_prec_t  get_default_prec()   {    return mpfr_get_default_prec();                            }
    172 
    173     // Constructors && type conversions
    174     mpreal();
    175     mpreal(const mpreal& u);
    176     mpreal(const mpf_t u);
    177     mpreal(const mpz_t u,             mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
    178     mpreal(const mpq_t u,             mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
    179     mpreal(const double u,            mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
    180     mpreal(const long double u,       mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
    181     mpreal(const unsigned long int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
    182     mpreal(const unsigned int u,      mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
    183     mpreal(const long int u,          mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
    184     mpreal(const int u,               mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd());
    185 
    186     // Construct mpreal from mpfr_t structure.
    187     // shared = true allows to avoid deep copy, so that mpreal and 'u' share the same data & pointers.
    188     mpreal(const mpfr_t  u, bool shared = false);
    189 
    190 #if defined (MPREAL_HAVE_INT64_SUPPORT)
    191     mpreal(const uint64_t u,          mp_prec_t prec = mpreal::get_default_prec(),  mp_rnd_t mode = mpreal::get_default_rnd());
    192     mpreal(const int64_t u,           mp_prec_t prec = mpreal::get_default_prec(),  mp_rnd_t mode = mpreal::get_default_rnd());
    193 #endif
    194 
    195     mpreal(const char* s,             mp_prec_t prec = mpreal::get_default_prec(), int base = 10, mp_rnd_t mode = mpreal::get_default_rnd());
    196     mpreal(const std::string& s,      mp_prec_t prec = mpreal::get_default_prec(), int base = 10, mp_rnd_t mode = mpreal::get_default_rnd());
    197 
    198     ~mpreal();
    199 
    200 #ifdef MPREAL_HAVE_MOVE_SUPPORT
    201     mpreal& operator=(mpreal&& v);
    202     mpreal(mpreal&& u);
    203 #endif
    204 
    205     // Operations
    206     // =
    207     // +, -, *, /, ++, --, <<, >>
    208     // *=, +=, -=, /=,
    209     // <, >, ==, <=, >=
    210 
    211     // =
    212     mpreal& operator=(const mpreal& v);
    213     mpreal& operator=(const mpf_t v);
    214     mpreal& operator=(const mpz_t v);
    215     mpreal& operator=(const mpq_t v);
    216     mpreal& operator=(const long double v);
    217     mpreal& operator=(const double v);
    218     mpreal& operator=(const unsigned long int v);
    219     mpreal& operator=(const unsigned int v);
    220     mpreal& operator=(const long int v);
    221     mpreal& operator=(const int v);
    222     mpreal& operator=(const char* s);
    223     mpreal& operator=(const std::string& s);
    224 
    225     // +
    226     mpreal& operator+=(const mpreal& v);
    227     mpreal& operator+=(const mpf_t v);
    228     mpreal& operator+=(const mpz_t v);
    229     mpreal& operator+=(const mpq_t v);
    230     mpreal& operator+=(const long double u);
    231     mpreal& operator+=(const double u);
    232     mpreal& operator+=(const unsigned long int u);
    233     mpreal& operator+=(const unsigned int u);
    234     mpreal& operator+=(const long int u);
    235     mpreal& operator+=(const int u);
    236 
    237 #if defined (MPREAL_HAVE_INT64_SUPPORT)
    238     mpreal& operator+=(const int64_t  u);
    239     mpreal& operator+=(const uint64_t u);
    240     mpreal& operator-=(const int64_t  u);
    241     mpreal& operator-=(const uint64_t u);
    242     mpreal& operator*=(const int64_t  u);
    243     mpreal& operator*=(const uint64_t u);
    244     mpreal& operator/=(const int64_t  u);
    245     mpreal& operator/=(const uint64_t u);
    246 #endif
    247 
    248     const mpreal operator+() const;
    249     mpreal& operator++ ();
    250     const mpreal  operator++ (int);
    251 
    252     // -
    253     mpreal& operator-=(const mpreal& v);
    254     mpreal& operator-=(const mpz_t v);
    255     mpreal& operator-=(const mpq_t v);
    256     mpreal& operator-=(const long double u);
    257     mpreal& operator-=(const double u);
    258     mpreal& operator-=(const unsigned long int u);
    259     mpreal& operator-=(const unsigned int u);
    260     mpreal& operator-=(const long int u);
    261     mpreal& operator-=(const int u);
    262     const mpreal operator-() const;
    263     friend const mpreal operator-(const unsigned long int b, const mpreal& a);
    264     friend const mpreal operator-(const unsigned int b,      const mpreal& a);
    265     friend const mpreal operator-(const long int b,          const mpreal& a);
    266     friend const mpreal operator-(const int b,               const mpreal& a);
    267     friend const mpreal operator-(const double b,            const mpreal& a);
    268     mpreal& operator-- ();
    269     const mpreal  operator-- (int);
    270 
    271     // *
    272     mpreal& operator*=(const mpreal& v);
    273     mpreal& operator*=(const mpz_t v);
    274     mpreal& operator*=(const mpq_t v);
    275     mpreal& operator*=(const long double v);
    276     mpreal& operator*=(const double v);
    277     mpreal& operator*=(const unsigned long int v);
    278     mpreal& operator*=(const unsigned int v);
    279     mpreal& operator*=(const long int v);
    280     mpreal& operator*=(const int v);
    281 
    282     // /
    283     mpreal& operator/=(const mpreal& v);
    284     mpreal& operator/=(const mpz_t v);
    285     mpreal& operator/=(const mpq_t v);
    286     mpreal& operator/=(const long double v);
    287     mpreal& operator/=(const double v);
    288     mpreal& operator/=(const unsigned long int v);
    289     mpreal& operator/=(const unsigned int v);
    290     mpreal& operator/=(const long int v);
    291     mpreal& operator/=(const int v);
    292     friend const mpreal operator/(const unsigned long int b, const mpreal& a);
    293     friend const mpreal operator/(const unsigned int b,      const mpreal& a);
    294     friend const mpreal operator/(const long int b,          const mpreal& a);
    295     friend const mpreal operator/(const int b,               const mpreal& a);
    296     friend const mpreal operator/(const double b,            const mpreal& a);
    297 
    298     //<<= Fast Multiplication by 2^u
    299     mpreal& operator<<=(const unsigned long int u);
    300     mpreal& operator<<=(const unsigned int u);
    301     mpreal& operator<<=(const long int u);
    302     mpreal& operator<<=(const int u);
    303 
    304     //>>= Fast Division by 2^u
    305     mpreal& operator>>=(const unsigned long int u);
    306     mpreal& operator>>=(const unsigned int u);
    307     mpreal& operator>>=(const long int u);
    308     mpreal& operator>>=(const int u);
    309 
    310     // Boolean Operators
    311     friend bool operator >  (const mpreal& a, const mpreal& b);
    312     friend bool operator >= (const mpreal& a, const mpreal& b);
    313     friend bool operator <  (const mpreal& a, const mpreal& b);
    314     friend bool operator <= (const mpreal& a, const mpreal& b);
    315     friend bool operator == (const mpreal& a, const mpreal& b);
    316     friend bool operator != (const mpreal& a, const mpreal& b);
    317 
    318     // Optimized specializations for boolean operators
    319     friend bool operator == (const mpreal& a, const unsigned long int b);
    320     friend bool operator == (const mpreal& a, const unsigned int b);
    321     friend bool operator == (const mpreal& a, const long int b);
    322     friend bool operator == (const mpreal& a, const int b);
    323     friend bool operator == (const mpreal& a, const long double b);
    324     friend bool operator == (const mpreal& a, const double b);
    325 
    326     // Type Conversion operators
    327     bool            toBool      (mp_rnd_t mode = GMP_RNDZ)    const;
    328     long            toLong      (mp_rnd_t mode = GMP_RNDZ)    const;
    329     unsigned long   toULong     (mp_rnd_t mode = GMP_RNDZ)    const;
    330     float           toFloat     (mp_rnd_t mode = GMP_RNDN)    const;
    331     double          toDouble    (mp_rnd_t mode = GMP_RNDN)    const;
    332     long double     toLDouble   (mp_rnd_t mode = GMP_RNDN)    const;
    333 
    334 #if defined (MPREAL_HAVE_EXPLICIT_CONVERTERS)
    335     explicit operator bool               () const { return toBool();       }
    336     explicit operator int                () const { return toLong();       }
    337     explicit operator long               () const { return toLong();       }
    338     explicit operator long long          () const { return toLong();       }
    339     explicit operator unsigned           () const { return toULong();      }
    340     explicit operator unsigned long      () const { return toULong();      }
    341     explicit operator unsigned long long () const { return toULong();      }
    342     explicit operator float              () const { return toFloat();      }
    343     explicit operator double             () const { return toDouble();     }
    344     explicit operator long double        () const { return toLDouble();    }
    345 #endif
    346 
    347 #if defined (MPREAL_HAVE_INT64_SUPPORT)
    348     int64_t         toInt64     (mp_rnd_t mode = GMP_RNDZ)    const;
    349     uint64_t        toUInt64    (mp_rnd_t mode = GMP_RNDZ)    const;
    350 
    351     #if defined (MPREAL_HAVE_EXPLICIT_CONVERTERS)
    352     explicit operator int64_t   () const { return toInt64();      }
    353     explicit operator uint64_t  () const { return toUInt64();     }
    354     #endif
    355 #endif
    356 
    357     // Get raw pointers so that mpreal can be directly used in raw mpfr_* functions
    358     ::mpfr_ptr    mpfr_ptr();
    359     ::mpfr_srcptr mpfr_ptr()    const;
    360     ::mpfr_srcptr mpfr_srcptr() const;
    361 
    362     // Convert mpreal to string with n significant digits in base b
    363     // n = -1 -> convert with the maximum available digits
    364     std::string toString(int n = -1, int b = 10, mp_rnd_t mode = mpreal::get_default_rnd()) const;
    365 
    366 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
    367     std::string toString(const std::string& format) const;
    368 #endif
    369 
    370     std::ostream& output(std::ostream& os) const;
    371 
    372     // Math Functions
    373     friend const mpreal sqr (const mpreal& v, mp_rnd_t rnd_mode);
    374     friend const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode);
    375     friend const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode);
    376     friend const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode);
    377     friend const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode);
    378     friend const mpreal pow (const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode);
    379     friend const mpreal pow (const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode);
    380     friend const mpreal pow (const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode);
    381     friend const mpreal pow (const mpreal& a, const long int b, mp_rnd_t rnd_mode);
    382     friend const mpreal pow (const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode);
    383     friend const mpreal pow (const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode);
    384     friend const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode);
    385 
    386     friend const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode);
    387     friend const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode);
    388     friend inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode);
    389     friend inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode);
    390     friend inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode);
    391     friend inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode);
    392     friend int cmpabs(const mpreal& a,const mpreal& b);
    393 
    394     friend const mpreal log  (const mpreal& v, mp_rnd_t rnd_mode);
    395     friend const mpreal log2 (const mpreal& v, mp_rnd_t rnd_mode);
    396     friend const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode);
    397     friend const mpreal exp  (const mpreal& v, mp_rnd_t rnd_mode);
    398     friend const mpreal exp2 (const mpreal& v, mp_rnd_t rnd_mode);
    399     friend const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode);
    400     friend const mpreal log1p(const mpreal& v, mp_rnd_t rnd_mode);
    401     friend const mpreal expm1(const mpreal& v, mp_rnd_t rnd_mode);
    402 
    403     friend const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode);
    404     friend const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode);
    405     friend const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode);
    406     friend const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode);
    407     friend const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode);
    408     friend const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode);
    409     friend int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode);
    410 
    411     friend const mpreal acos  (const mpreal& v, mp_rnd_t rnd_mode);
    412     friend const mpreal asin  (const mpreal& v, mp_rnd_t rnd_mode);
    413     friend const mpreal atan  (const mpreal& v, mp_rnd_t rnd_mode);
    414     friend const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode);
    415     friend const mpreal acot  (const mpreal& v, mp_rnd_t rnd_mode);
    416     friend const mpreal asec  (const mpreal& v, mp_rnd_t rnd_mode);
    417     friend const mpreal acsc  (const mpreal& v, mp_rnd_t rnd_mode);
    418 
    419     friend const mpreal cosh  (const mpreal& v, mp_rnd_t rnd_mode);
    420     friend const mpreal sinh  (const mpreal& v, mp_rnd_t rnd_mode);
    421     friend const mpreal tanh  (const mpreal& v, mp_rnd_t rnd_mode);
    422     friend const mpreal sech  (const mpreal& v, mp_rnd_t rnd_mode);
    423     friend const mpreal csch  (const mpreal& v, mp_rnd_t rnd_mode);
    424     friend const mpreal coth  (const mpreal& v, mp_rnd_t rnd_mode);
    425     friend const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode);
    426     friend const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode);
    427     friend const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode);
    428     friend const mpreal acoth (const mpreal& v, mp_rnd_t rnd_mode);
    429     friend const mpreal asech (const mpreal& v, mp_rnd_t rnd_mode);
    430     friend const mpreal acsch (const mpreal& v, mp_rnd_t rnd_mode);
    431 
    432     friend const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
    433 
    434     friend const mpreal fac_ui (unsigned long int v,  mp_prec_t prec, mp_rnd_t rnd_mode);
    435     friend const mpreal eint   (const mpreal& v, mp_rnd_t rnd_mode);
    436 
    437     friend const mpreal gamma    (const mpreal& v, mp_rnd_t rnd_mode);
    438     friend const mpreal lngamma  (const mpreal& v, mp_rnd_t rnd_mode);
    439     friend const mpreal lgamma   (const mpreal& v, int *signp, mp_rnd_t rnd_mode);
    440     friend const mpreal zeta     (const mpreal& v, mp_rnd_t rnd_mode);
    441     friend const mpreal erf      (const mpreal& v, mp_rnd_t rnd_mode);
    442     friend const mpreal erfc     (const mpreal& v, mp_rnd_t rnd_mode);
    443     friend const mpreal besselj0 (const mpreal& v, mp_rnd_t rnd_mode);
    444     friend const mpreal besselj1 (const mpreal& v, mp_rnd_t rnd_mode);
    445     friend const mpreal besseljn (long n, const mpreal& v, mp_rnd_t rnd_mode);
    446     friend const mpreal bessely0 (const mpreal& v, mp_rnd_t rnd_mode);
    447     friend const mpreal bessely1 (const mpreal& v, mp_rnd_t rnd_mode);
    448     friend const mpreal besselyn (long n, const mpreal& v, mp_rnd_t rnd_mode);
    449     friend const mpreal fma      (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode);
    450     friend const mpreal fms      (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode);
    451     friend const mpreal agm      (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode);
    452     friend const mpreal sum      (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode);
    453     friend int sgn(const mpreal& v); // returns -1 or +1
    454 
    455 // MPFR 2.4.0 Specifics
    456 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
    457     friend int          sinh_cosh   (mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode);
    458     friend const mpreal li2         (const mpreal& v,                       mp_rnd_t rnd_mode);
    459     friend const mpreal fmod        (const mpreal& x, const mpreal& y,      mp_rnd_t rnd_mode);
    460     friend const mpreal rec_sqrt    (const mpreal& v,                       mp_rnd_t rnd_mode);
    461 
    462     // MATLAB's semantic equivalents
    463     friend const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Remainder after division
    464     friend const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Modulus after division
    465 #endif
    466 
    467 // MPFR 3.0.0 Specifics
    468 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
    469     friend const mpreal digamma (const mpreal& v,        mp_rnd_t rnd_mode);
    470     friend const mpreal ai      (const mpreal& v,        mp_rnd_t rnd_mode);
    471     friend const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode);     // use gmp_randinit_default() to init state, gmp_randclear() to clear
    472     friend const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode);     // use gmp_randinit_default() to init state, gmp_randclear() to clear
    473     friend const mpreal grandom (unsigned int seed);
    474 #endif
    475 
    476     // Uniformly distributed random number generation in [0,1] using
    477     // Mersenne-Twister algorithm by default.
    478     // Use parameter to setup seed, e.g.: random((unsigned)time(NULL))
    479     // Check urandom() for more precise control.
    480     friend const mpreal random(unsigned int seed);
    481 
    482     // Exponent and mantissa manipulation
    483     friend const mpreal frexp(const mpreal& v, mp_exp_t* exp);
    484     friend const mpreal ldexp(const mpreal& v, mp_exp_t exp);
    485 
    486     // Splits mpreal value into fractional and integer parts.
    487     // Returns fractional part and stores integer part in n.
    488     friend const mpreal modf(const mpreal& v, mpreal& n);
    489 
    490     // Constants
    491     // don't forget to call mpfr_free_cache() for every thread where you are using const-functions
    492     friend const mpreal const_log2      (mp_prec_t prec, mp_rnd_t rnd_mode);
    493     friend const mpreal const_pi        (mp_prec_t prec, mp_rnd_t rnd_mode);
    494     friend const mpreal const_euler     (mp_prec_t prec, mp_rnd_t rnd_mode);
    495     friend const mpreal const_catalan   (mp_prec_t prec, mp_rnd_t rnd_mode);
    496 
    497     // returns +inf iff sign>=0 otherwise -inf
    498     friend const mpreal const_infinity(int sign, mp_prec_t prec);
    499 
    500     // Output/ Input
    501     friend std::ostream& operator<<(std::ostream& os, const mpreal& v);
    502     friend std::istream& operator>>(std::istream& is, mpreal& v);
    503 
    504     // Integer Related Functions
    505     friend const mpreal rint (const mpreal& v, mp_rnd_t rnd_mode);
    506     friend const mpreal ceil (const mpreal& v);
    507     friend const mpreal floor(const mpreal& v);
    508     friend const mpreal round(const mpreal& v);
    509     friend const mpreal trunc(const mpreal& v);
    510     friend const mpreal rint_ceil   (const mpreal& v, mp_rnd_t rnd_mode);
    511     friend const mpreal rint_floor  (const mpreal& v, mp_rnd_t rnd_mode);
    512     friend const mpreal rint_round  (const mpreal& v, mp_rnd_t rnd_mode);
    513     friend const mpreal rint_trunc  (const mpreal& v, mp_rnd_t rnd_mode);
    514     friend const mpreal frac        (const mpreal& v, mp_rnd_t rnd_mode);
    515     friend const mpreal remainder   (         const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
    516     friend const mpreal remquo      (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
    517 
    518     // Miscellaneous Functions
    519     friend const mpreal nexttoward (const mpreal& x, const mpreal& y);
    520     friend const mpreal nextabove  (const mpreal& x);
    521     friend const mpreal nextbelow  (const mpreal& x);
    522 
    523     // use gmp_randinit_default() to init state, gmp_randclear() to clear
    524     friend const mpreal urandomb (gmp_randstate_t& state);
    525 
    526 // MPFR < 2.4.2 Specifics
    527 #if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2))
    528     friend const mpreal random2 (mp_size_t size, mp_exp_t exp);
    529 #endif
    530 
    531     // Instance Checkers
    532     friend bool isnan    (const mpreal& v);
    533     friend bool isinf    (const mpreal& v);
    534     friend bool isfinite (const mpreal& v);
    535 
    536     friend bool isnum    (const mpreal& v);
    537     friend bool iszero   (const mpreal& v);
    538     friend bool isint    (const mpreal& v);
    539 
    540 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
    541     friend bool isregular(const mpreal& v);
    542 #endif
    543 
    544     // Set/Get instance properties
    545     inline mp_prec_t    get_prec() const;
    546     inline void         set_prec(mp_prec_t prec, mp_rnd_t rnd_mode = get_default_rnd());    // Change precision with rounding mode
    547 
    548     // Aliases for get_prec(), set_prec() - needed for compatibility with std::complex<mpreal> interface
    549     inline mpreal&      setPrecision(int Precision, mp_rnd_t RoundingMode = get_default_rnd());
    550     inline int          getPrecision() const;
    551 
    552     // Set mpreal to +/- inf, NaN, +/-0
    553     mpreal&        setInf  (int Sign = +1);
    554     mpreal&        setNan  ();
    555     mpreal&        setZero (int Sign = +1);
    556     mpreal&        setSign (int Sign, mp_rnd_t RoundingMode = get_default_rnd());
    557 
    558     //Exponent
    559     mp_exp_t get_exp();
    560     int set_exp(mp_exp_t e);
    561     int check_range  (int t, mp_rnd_t rnd_mode = get_default_rnd());
    562     int subnormalize (int t,mp_rnd_t rnd_mode = get_default_rnd());
    563 
    564     // Inexact conversion from float
    565     inline bool fits_in_bits(double x, int n);
    566 
    567     // Set/Get global properties
    568     static void            set_default_prec(mp_prec_t prec);
    569     static void            set_default_rnd(mp_rnd_t rnd_mode);
    570 
    571     static mp_exp_t  get_emin (void);
    572     static mp_exp_t  get_emax (void);
    573     static mp_exp_t  get_emin_min (void);
    574     static mp_exp_t  get_emin_max (void);
    575     static mp_exp_t  get_emax_min (void);
    576     static mp_exp_t  get_emax_max (void);
    577     static int       set_emin (mp_exp_t exp);
    578     static int       set_emax (mp_exp_t exp);
    579 
    580     // Efficient swapping of two mpreal values - needed for std algorithms
    581     friend void swap(mpreal& x, mpreal& y);
    582 
    583     friend const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
    584     friend const mpreal fmin(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode);
    585 
    586 private:
    587     // Human friendly Debug Preview in Visual Studio.
    588     // Put one of these lines:
    589     //
    590     // mpfr::mpreal=<DebugView>                              ; Show value only
    591     // mpfr::mpreal=<DebugView>, <mp[0]._mpfr_prec,u>bits    ; Show value & precision
    592     //
    593     // at the beginning of
    594     // [Visual Studio Installation Folder]\Common7\Packages\Debugger\autoexp.dat
    595     MPREAL_MSVC_DEBUGVIEW_DATA
    596 
    597     // "Smart" resources deallocation. Checks if instance initialized before deletion.
    598     void clear(::mpfr_ptr);
    599 };
    600 
    601 //////////////////////////////////////////////////////////////////////////
    602 // Exceptions
    603 class conversion_overflow : public std::exception {
    604 public:
    605     std::string why() { return "inexact conversion from floating point"; }
    606 };
    607 
    608 //////////////////////////////////////////////////////////////////////////
    609 // Constructors & converters
    610 // Default constructor: creates mp number and initializes it to 0.
    611 inline mpreal::mpreal()
    612 {
    613     mpfr_init2 (mpfr_ptr(), mpreal::get_default_prec());
    614     mpfr_set_ui(mpfr_ptr(), 0, mpreal::get_default_rnd());
    615 
    616     MPREAL_MSVC_DEBUGVIEW_CODE;
    617 }
    618 
    619 inline mpreal::mpreal(const mpreal& u)
    620 {
    621     mpfr_init2(mpfr_ptr(),mpfr_get_prec(u.mpfr_srcptr()));
    622     mpfr_set  (mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd());
    623 
    624     MPREAL_MSVC_DEBUGVIEW_CODE;
    625 }
    626 
    627 #ifdef MPREAL_HAVE_MOVE_SUPPORT
    628 inline mpreal::mpreal(mpreal&& other)
    629 {
    630     mpfr_set_uninitialized(mpfr_ptr());     // make sure "other" holds no pinter to actual data
    631     mpfr_swap(mpfr_ptr(), other.mpfr_ptr());
    632 
    633     MPREAL_MSVC_DEBUGVIEW_CODE;
    634 }
    635 
    636 inline mpreal& mpreal::operator=(mpreal&& other)
    637 {
    638     mpfr_swap(mpfr_ptr(), other.mpfr_ptr());
    639 
    640     MPREAL_MSVC_DEBUGVIEW_CODE;
    641     return *this;
    642 }
    643 #endif
    644 
    645 inline mpreal::mpreal(const mpfr_t  u, bool shared)
    646 {
    647     if(shared)
    648     {
    649         std::memcpy(mpfr_ptr(), u, sizeof(mpfr_t));
    650     }
    651     else
    652     {
    653         mpfr_init2(mpfr_ptr(), mpfr_get_prec(u));
    654         mpfr_set  (mpfr_ptr(), u, mpreal::get_default_rnd());
    655     }
    656 
    657     MPREAL_MSVC_DEBUGVIEW_CODE;
    658 }
    659 
    660 inline mpreal::mpreal(const mpf_t u)
    661 {
    662     mpfr_init2(mpfr_ptr(),(mp_prec_t) mpf_get_prec(u)); // (gmp: mp_bitcnt_t) unsigned long -> long (mpfr: mp_prec_t)
    663     mpfr_set_f(mpfr_ptr(),u,mpreal::get_default_rnd());
    664 
    665     MPREAL_MSVC_DEBUGVIEW_CODE;
    666 }
    667 
    668 inline mpreal::mpreal(const mpz_t u, mp_prec_t prec, mp_rnd_t mode)
    669 {
    670     mpfr_init2(mpfr_ptr(), prec);
    671     mpfr_set_z(mpfr_ptr(), u, mode);
    672 
    673     MPREAL_MSVC_DEBUGVIEW_CODE;
    674 }
    675 
    676 inline mpreal::mpreal(const mpq_t u, mp_prec_t prec, mp_rnd_t mode)
    677 {
    678     mpfr_init2(mpfr_ptr(), prec);
    679     mpfr_set_q(mpfr_ptr(), u, mode);
    680 
    681     MPREAL_MSVC_DEBUGVIEW_CODE;
    682 }
    683 
    684 inline mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode)
    685 {
    686      mpfr_init2(mpfr_ptr(), prec);
    687 
    688 #if (MPREAL_DOUBLE_BITS_OVERFLOW > -1)
    689   if(fits_in_bits(u, MPREAL_DOUBLE_BITS_OVERFLOW))
    690   {
    691     mpfr_set_d(mpfr_ptr(), u, mode);
    692   }else
    693     throw conversion_overflow();
    694 #else
    695   mpfr_set_d(mpfr_ptr(), u, mode);
    696 #endif
    697 
    698     MPREAL_MSVC_DEBUGVIEW_CODE;
    699 }
    700 
    701 inline mpreal::mpreal(const long double u, mp_prec_t prec, mp_rnd_t mode)
    702 {
    703     mpfr_init2 (mpfr_ptr(), prec);
    704     mpfr_set_ld(mpfr_ptr(), u, mode);
    705 
    706     MPREAL_MSVC_DEBUGVIEW_CODE;
    707 }
    708 
    709 inline mpreal::mpreal(const unsigned long int u, mp_prec_t prec, mp_rnd_t mode)
    710 {
    711     mpfr_init2 (mpfr_ptr(), prec);
    712     mpfr_set_ui(mpfr_ptr(), u, mode);
    713 
    714     MPREAL_MSVC_DEBUGVIEW_CODE;
    715 }
    716 
    717 inline mpreal::mpreal(const unsigned int u, mp_prec_t prec, mp_rnd_t mode)
    718 {
    719     mpfr_init2 (mpfr_ptr(), prec);
    720     mpfr_set_ui(mpfr_ptr(), u, mode);
    721 
    722     MPREAL_MSVC_DEBUGVIEW_CODE;
    723 }
    724 
    725 inline mpreal::mpreal(const long int u, mp_prec_t prec, mp_rnd_t mode)
    726 {
    727     mpfr_init2 (mpfr_ptr(), prec);
    728     mpfr_set_si(mpfr_ptr(), u, mode);
    729 
    730     MPREAL_MSVC_DEBUGVIEW_CODE;
    731 }
    732 
    733 inline mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode)
    734 {
    735     mpfr_init2 (mpfr_ptr(), prec);
    736     mpfr_set_si(mpfr_ptr(), u, mode);
    737 
    738     MPREAL_MSVC_DEBUGVIEW_CODE;
    739 }
    740 
    741 #if defined (MPREAL_HAVE_INT64_SUPPORT)
    742 inline mpreal::mpreal(const uint64_t u, mp_prec_t prec, mp_rnd_t mode)
    743 {
    744     mpfr_init2 (mpfr_ptr(), prec);
    745     mpfr_set_uj(mpfr_ptr(), u, mode);
    746 
    747     MPREAL_MSVC_DEBUGVIEW_CODE;
    748 }
    749 
    750 inline mpreal::mpreal(const int64_t u, mp_prec_t prec, mp_rnd_t mode)
    751 {
    752     mpfr_init2 (mpfr_ptr(), prec);
    753     mpfr_set_sj(mpfr_ptr(), u, mode);
    754 
    755     MPREAL_MSVC_DEBUGVIEW_CODE;
    756 }
    757 #endif
    758 
    759 inline mpreal::mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode)
    760 {
    761     mpfr_init2  (mpfr_ptr(), prec);
    762     mpfr_set_str(mpfr_ptr(), s, base, mode);
    763 
    764     MPREAL_MSVC_DEBUGVIEW_CODE;
    765 }
    766 
    767 inline mpreal::mpreal(const std::string& s, mp_prec_t prec, int base, mp_rnd_t mode)
    768 {
    769     mpfr_init2  (mpfr_ptr(), prec);
    770     mpfr_set_str(mpfr_ptr(), s.c_str(), base, mode);
    771 
    772     MPREAL_MSVC_DEBUGVIEW_CODE;
    773 }
    774 
    775 inline void mpreal::clear(::mpfr_ptr x)
    776 {
    777 #ifdef MPREAL_HAVE_MOVE_SUPPORT
    778     if(mpfr_is_initialized(x))
    779 #endif
    780     mpfr_clear(x);
    781 }
    782 
    783 inline mpreal::~mpreal()
    784 {
    785     clear(mpfr_ptr());
    786 }
    787 
    788 // internal namespace needed for template magic
    789 namespace internal{
    790 
    791     // Use SFINAE to restrict arithmetic operations instantiation only for numeric types
    792     // This is needed for smooth integration with libraries based on expression templates, like Eigen.
    793     // TODO: Do the same for boolean operators.
    794     template <typename ArgumentType> struct result_type {};
    795 
    796     template <> struct result_type<mpreal>              {typedef mpreal type;};
    797     template <> struct result_type<mpz_t>               {typedef mpreal type;};
    798     template <> struct result_type<mpq_t>               {typedef mpreal type;};
    799     template <> struct result_type<long double>         {typedef mpreal type;};
    800     template <> struct result_type<double>              {typedef mpreal type;};
    801     template <> struct result_type<unsigned long int>   {typedef mpreal type;};
    802     template <> struct result_type<unsigned int>        {typedef mpreal type;};
    803     template <> struct result_type<long int>            {typedef mpreal type;};
    804     template <> struct result_type<int>                 {typedef mpreal type;};
    805 
    806 #if defined (MPREAL_HAVE_INT64_SUPPORT)
    807     template <> struct result_type<int64_t  >           {typedef mpreal type;};
    808     template <> struct result_type<uint64_t >           {typedef mpreal type;};
    809 #endif
    810 }
    811 
    812 // + Addition
    813 template <typename Rhs>
    814 inline const typename internal::result_type<Rhs>::type
    815     operator+(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) += rhs;    }
    816 
    817 template <typename Lhs>
    818 inline const typename internal::result_type<Lhs>::type
    819     operator+(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) += lhs;    }
    820 
    821 // - Subtraction
    822 template <typename Rhs>
    823 inline const typename internal::result_type<Rhs>::type
    824     operator-(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) -= rhs;    }
    825 
    826 template <typename Lhs>
    827 inline const typename internal::result_type<Lhs>::type
    828     operator-(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) -= rhs;    }
    829 
    830 // * Multiplication
    831 template <typename Rhs>
    832 inline const typename internal::result_type<Rhs>::type
    833     operator*(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) *= rhs;    }
    834 
    835 template <typename Lhs>
    836 inline const typename internal::result_type<Lhs>::type
    837     operator*(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) *= lhs;    }
    838 
    839 // / Division
    840 template <typename Rhs>
    841 inline const typename internal::result_type<Rhs>::type
    842     operator/(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) /= rhs;    }
    843 
    844 template <typename Lhs>
    845 inline const typename internal::result_type<Lhs>::type
    846     operator/(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) /= rhs;    }
    847 
    848 //////////////////////////////////////////////////////////////////////////
    849 // sqrt
    850 const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    851 const mpreal sqrt(const long int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    852 const mpreal sqrt(const int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    853 const mpreal sqrt(const long double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    854 const mpreal sqrt(const double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    855 
    856 // abs
    857 inline const mpreal abs(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd());
    858 
    859 //////////////////////////////////////////////////////////////////////////
    860 // pow
    861 const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    862 const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    863 const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    864 const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    865 
    866 const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    867 const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    868 const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    869 const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    870 const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    871 
    872 const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    873 const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    874 const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    875 const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    876 const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    877 
    878 const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    879 const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    880 const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    881 const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    882 const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    883 const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    884 
    885 const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    886 const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    887 const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    888 const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    889 const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    890 const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    891 
    892 const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    893 const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    894 const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    895 const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    896 const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    897 const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    898 
    899 const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    900 const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    901 const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    902 const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    903 const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    904 
    905 const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    906 const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    907 const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    908 const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    909 const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    910 
    911 inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    912 inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    913 inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    914 inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd());
    915 
    916 //////////////////////////////////////////////////////////////////////////
    917 // Estimate machine epsilon for the given precision
    918 // Returns smallest eps such that 1.0 + eps != 1.0
    919 inline mpreal machine_epsilon(mp_prec_t prec = mpreal::get_default_prec());
    920 
    921 // Returns smallest eps such that x + eps != x (relative machine epsilon)
    922 inline mpreal machine_epsilon(const mpreal& x);
    923 
    924 // Gives max & min values for the required precision,
    925 // minval is 'safe' meaning 1 / minval does not overflow
    926 // maxval is 'safe' meaning 1 / maxval does not underflow
    927 inline mpreal minval(mp_prec_t prec = mpreal::get_default_prec());
    928 inline mpreal maxval(mp_prec_t prec = mpreal::get_default_prec());
    929 
    930 // 'Dirty' equality check 1: |a-b| < min{|a|,|b|} * eps
    931 inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps);
    932 
    933 // 'Dirty' equality check 2: |a-b| < min{|a|,|b|} * eps( min{|a|,|b|} )
    934 inline bool isEqualFuzzy(const mpreal& a, const mpreal& b);
    935 
    936 // 'Bitwise' equality check
    937 //  maxUlps - a and b can be apart by maxUlps binary numbers.
    938 inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps);
    939 
    940 //////////////////////////////////////////////////////////////////////////
    941 //     Convert precision in 'bits' to decimal digits and vice versa.
    942 //        bits   = ceil(digits*log[2](10))
    943 //        digits = floor(bits*log[10](2))
    944 
    945 inline mp_prec_t digits2bits(int d);
    946 inline int       bits2digits(mp_prec_t b);
    947 
    948 //////////////////////////////////////////////////////////////////////////
    949 // min, max
    950 const mpreal (max)(const mpreal& x, const mpreal& y);
    951 const mpreal (min)(const mpreal& x, const mpreal& y);
    952 
    953 //////////////////////////////////////////////////////////////////////////
    954 // Implementation
    955 //////////////////////////////////////////////////////////////////////////
    956 
    957 //////////////////////////////////////////////////////////////////////////
    958 // Operators - Assignment
    959 inline mpreal& mpreal::operator=(const mpreal& v)
    960 {
    961     if (this != &v)
    962     {
    963     mp_prec_t tp = mpfr_get_prec(  mpfr_srcptr());
    964     mp_prec_t vp = mpfr_get_prec(v.mpfr_srcptr());
    965 
    966     if(tp != vp){
    967       clear(mpfr_ptr());
    968       mpfr_init2(mpfr_ptr(), vp);
    969     }
    970 
    971         mpfr_set(mpfr_ptr(), v.mpfr_srcptr(), mpreal::get_default_rnd());
    972 
    973         MPREAL_MSVC_DEBUGVIEW_CODE;
    974     }
    975     return *this;
    976 }
    977 
    978 inline mpreal& mpreal::operator=(const mpf_t v)
    979 {
    980     mpfr_set_f(mpfr_ptr(), v, mpreal::get_default_rnd());
    981 
    982     MPREAL_MSVC_DEBUGVIEW_CODE;
    983     return *this;
    984 }
    985 
    986 inline mpreal& mpreal::operator=(const mpz_t v)
    987 {
    988     mpfr_set_z(mpfr_ptr(), v, mpreal::get_default_rnd());
    989 
    990     MPREAL_MSVC_DEBUGVIEW_CODE;
    991     return *this;
    992 }
    993 
    994 inline mpreal& mpreal::operator=(const mpq_t v)
    995 {
    996     mpfr_set_q(mpfr_ptr(), v, mpreal::get_default_rnd());
    997 
    998     MPREAL_MSVC_DEBUGVIEW_CODE;
    999     return *this;
   1000 }
   1001 
   1002 inline mpreal& mpreal::operator=(const long double v)
   1003 {
   1004     mpfr_set_ld(mpfr_ptr(), v, mpreal::get_default_rnd());
   1005 
   1006     MPREAL_MSVC_DEBUGVIEW_CODE;
   1007     return *this;
   1008 }
   1009 
   1010 inline mpreal& mpreal::operator=(const double v)
   1011 {
   1012 #if (MPREAL_DOUBLE_BITS_OVERFLOW > -1)
   1013   if(fits_in_bits(v, MPREAL_DOUBLE_BITS_OVERFLOW))
   1014   {
   1015     mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd());
   1016   }else
   1017     throw conversion_overflow();
   1018 #else
   1019   mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd());
   1020 #endif
   1021 
   1022   MPREAL_MSVC_DEBUGVIEW_CODE;
   1023     return *this;
   1024 }
   1025 
   1026 inline mpreal& mpreal::operator=(const unsigned long int v)
   1027 {
   1028     mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd());
   1029 
   1030     MPREAL_MSVC_DEBUGVIEW_CODE;
   1031     return *this;
   1032 }
   1033 
   1034 inline mpreal& mpreal::operator=(const unsigned int v)
   1035 {
   1036     mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd());
   1037 
   1038     MPREAL_MSVC_DEBUGVIEW_CODE;
   1039     return *this;
   1040 }
   1041 
   1042 inline mpreal& mpreal::operator=(const long int v)
   1043 {
   1044     mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd());
   1045 
   1046     MPREAL_MSVC_DEBUGVIEW_CODE;
   1047     return *this;
   1048 }
   1049 
   1050 inline mpreal& mpreal::operator=(const int v)
   1051 {
   1052     mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd());
   1053 
   1054     MPREAL_MSVC_DEBUGVIEW_CODE;
   1055     return *this;
   1056 }
   1057 
   1058 inline mpreal& mpreal::operator=(const char* s)
   1059 {
   1060     // Use other converters for more precise control on base & precision & rounding:
   1061     //
   1062     //        mpreal(const char* s,        mp_prec_t prec, int base, mp_rnd_t mode)
   1063     //        mpreal(const std::string& s,mp_prec_t prec, int base, mp_rnd_t mode)
   1064     //
   1065     // Here we assume base = 10 and we use precision of target variable.
   1066 
   1067     mpfr_t t;
   1068 
   1069     mpfr_init2(t, mpfr_get_prec(mpfr_srcptr()));
   1070 
   1071     if(0 == mpfr_set_str(t, s, 10, mpreal::get_default_rnd()))
   1072     {
   1073         mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd());
   1074         MPREAL_MSVC_DEBUGVIEW_CODE;
   1075     }
   1076 
   1077     clear(t);
   1078     return *this;
   1079 }
   1080 
   1081 inline mpreal& mpreal::operator=(const std::string& s)
   1082 {
   1083     // Use other converters for more precise control on base & precision & rounding:
   1084     //
   1085     //        mpreal(const char* s,        mp_prec_t prec, int base, mp_rnd_t mode)
   1086     //        mpreal(const std::string& s,mp_prec_t prec, int base, mp_rnd_t mode)
   1087     //
   1088     // Here we assume base = 10 and we use precision of target variable.
   1089 
   1090     mpfr_t t;
   1091 
   1092     mpfr_init2(t, mpfr_get_prec(mpfr_srcptr()));
   1093 
   1094     if(0 == mpfr_set_str(t, s.c_str(), 10, mpreal::get_default_rnd()))
   1095     {
   1096         mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd());
   1097         MPREAL_MSVC_DEBUGVIEW_CODE;
   1098     }
   1099 
   1100     clear(t);
   1101     return *this;
   1102 }
   1103 
   1104 
   1105 //////////////////////////////////////////////////////////////////////////
   1106 // + Addition
   1107 inline mpreal& mpreal::operator+=(const mpreal& v)
   1108 {
   1109     mpfr_add(mpfr_ptr(), mpfr_srcptr(), v.mpfr_srcptr(), mpreal::get_default_rnd());
   1110     MPREAL_MSVC_DEBUGVIEW_CODE;
   1111     return *this;
   1112 }
   1113 
   1114 inline mpreal& mpreal::operator+=(const mpf_t u)
   1115 {
   1116     *this += mpreal(u);
   1117     MPREAL_MSVC_DEBUGVIEW_CODE;
   1118     return *this;
   1119 }
   1120 
   1121 inline mpreal& mpreal::operator+=(const mpz_t u)
   1122 {
   1123     mpfr_add_z(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1124     MPREAL_MSVC_DEBUGVIEW_CODE;
   1125     return *this;
   1126 }
   1127 
   1128 inline mpreal& mpreal::operator+=(const mpq_t u)
   1129 {
   1130     mpfr_add_q(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1131     MPREAL_MSVC_DEBUGVIEW_CODE;
   1132     return *this;
   1133 }
   1134 
   1135 inline mpreal& mpreal::operator+= (const long double u)
   1136 {
   1137     *this += mpreal(u);
   1138     MPREAL_MSVC_DEBUGVIEW_CODE;
   1139     return *this;
   1140 }
   1141 
   1142 inline mpreal& mpreal::operator+= (const double u)
   1143 {
   1144 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
   1145     mpfr_add_d(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1146 #else
   1147     *this += mpreal(u);
   1148 #endif
   1149 
   1150     MPREAL_MSVC_DEBUGVIEW_CODE;
   1151     return *this;
   1152 }
   1153 
   1154 inline mpreal& mpreal::operator+=(const unsigned long int u)
   1155 {
   1156     mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1157     MPREAL_MSVC_DEBUGVIEW_CODE;
   1158     return *this;
   1159 }
   1160 
   1161 inline mpreal& mpreal::operator+=(const unsigned int u)
   1162 {
   1163     mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1164     MPREAL_MSVC_DEBUGVIEW_CODE;
   1165     return *this;
   1166 }
   1167 
   1168 inline mpreal& mpreal::operator+=(const long int u)
   1169 {
   1170     mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1171     MPREAL_MSVC_DEBUGVIEW_CODE;
   1172     return *this;
   1173 }
   1174 
   1175 inline mpreal& mpreal::operator+=(const int u)
   1176 {
   1177     mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1178     MPREAL_MSVC_DEBUGVIEW_CODE;
   1179     return *this;
   1180 }
   1181 
   1182 #if defined (MPREAL_HAVE_INT64_SUPPORT)
   1183 inline mpreal& mpreal::operator+=(const int64_t  u){    *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
   1184 inline mpreal& mpreal::operator+=(const uint64_t u){    *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
   1185 inline mpreal& mpreal::operator-=(const int64_t  u){    *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
   1186 inline mpreal& mpreal::operator-=(const uint64_t u){    *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
   1187 inline mpreal& mpreal::operator*=(const int64_t  u){    *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
   1188 inline mpreal& mpreal::operator*=(const uint64_t u){    *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
   1189 inline mpreal& mpreal::operator/=(const int64_t  u){    *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
   1190 inline mpreal& mpreal::operator/=(const uint64_t u){    *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;    }
   1191 #endif
   1192 
   1193 inline const mpreal mpreal::operator+()const    {    return mpreal(*this); }
   1194 
   1195 inline const mpreal operator+(const mpreal& a, const mpreal& b)
   1196 {
   1197   mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr())));
   1198   mpfr_add(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd());
   1199   return c;
   1200 }
   1201 
   1202 inline mpreal& mpreal::operator++()
   1203 {
   1204     return *this += 1;
   1205 }
   1206 
   1207 inline const mpreal mpreal::operator++ (int)
   1208 {
   1209     mpreal x(*this);
   1210     *this += 1;
   1211     return x;
   1212 }
   1213 
   1214 inline mpreal& mpreal::operator--()
   1215 {
   1216     return *this -= 1;
   1217 }
   1218 
   1219 inline const mpreal mpreal::operator-- (int)
   1220 {
   1221     mpreal x(*this);
   1222     *this -= 1;
   1223     return x;
   1224 }
   1225 
   1226 //////////////////////////////////////////////////////////////////////////
   1227 // - Subtraction
   1228 inline mpreal& mpreal::operator-=(const mpreal& v)
   1229 {
   1230     mpfr_sub(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd());
   1231     MPREAL_MSVC_DEBUGVIEW_CODE;
   1232     return *this;
   1233 }
   1234 
   1235 inline mpreal& mpreal::operator-=(const mpz_t v)
   1236 {
   1237     mpfr_sub_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1238     MPREAL_MSVC_DEBUGVIEW_CODE;
   1239     return *this;
   1240 }
   1241 
   1242 inline mpreal& mpreal::operator-=(const mpq_t v)
   1243 {
   1244     mpfr_sub_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1245     MPREAL_MSVC_DEBUGVIEW_CODE;
   1246     return *this;
   1247 }
   1248 
   1249 inline mpreal& mpreal::operator-=(const long double v)
   1250 {
   1251     *this -= mpreal(v);
   1252     MPREAL_MSVC_DEBUGVIEW_CODE;
   1253     return *this;
   1254 }
   1255 
   1256 inline mpreal& mpreal::operator-=(const double v)
   1257 {
   1258 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
   1259     mpfr_sub_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1260 #else
   1261     *this -= mpreal(v);
   1262 #endif
   1263 
   1264     MPREAL_MSVC_DEBUGVIEW_CODE;
   1265     return *this;
   1266 }
   1267 
   1268 inline mpreal& mpreal::operator-=(const unsigned long int v)
   1269 {
   1270     mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1271     MPREAL_MSVC_DEBUGVIEW_CODE;
   1272     return *this;
   1273 }
   1274 
   1275 inline mpreal& mpreal::operator-=(const unsigned int v)
   1276 {
   1277     mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1278     MPREAL_MSVC_DEBUGVIEW_CODE;
   1279     return *this;
   1280 }
   1281 
   1282 inline mpreal& mpreal::operator-=(const long int v)
   1283 {
   1284     mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1285     MPREAL_MSVC_DEBUGVIEW_CODE;
   1286     return *this;
   1287 }
   1288 
   1289 inline mpreal& mpreal::operator-=(const int v)
   1290 {
   1291     mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1292     MPREAL_MSVC_DEBUGVIEW_CODE;
   1293     return *this;
   1294 }
   1295 
   1296 inline const mpreal mpreal::operator-()const
   1297 {
   1298     mpreal u(*this);
   1299     mpfr_neg(u.mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd());
   1300     return u;
   1301 }
   1302 
   1303 inline const mpreal operator-(const mpreal& a, const mpreal& b)
   1304 {
   1305   mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr())));
   1306   mpfr_sub(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd());
   1307   return c;
   1308 }
   1309 
   1310 inline const mpreal operator-(const double  b, const mpreal& a)
   1311 {
   1312 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
   1313     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
   1314     mpfr_d_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1315     return x;
   1316 #else
   1317     mpreal x(b, mpfr_get_prec(a.mpfr_ptr()));
   1318     x -= a;
   1319     return x;
   1320 #endif
   1321 }
   1322 
   1323 inline const mpreal operator-(const unsigned long int b, const mpreal& a)
   1324 {
   1325     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
   1326     mpfr_ui_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1327     return x;
   1328 }
   1329 
   1330 inline const mpreal operator-(const unsigned int b, const mpreal& a)
   1331 {
   1332     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
   1333     mpfr_ui_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1334     return x;
   1335 }
   1336 
   1337 inline const mpreal operator-(const long int b, const mpreal& a)
   1338 {
   1339     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
   1340     mpfr_si_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1341     return x;
   1342 }
   1343 
   1344 inline const mpreal operator-(const int b, const mpreal& a)
   1345 {
   1346     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
   1347     mpfr_si_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1348     return x;
   1349 }
   1350 
   1351 //////////////////////////////////////////////////////////////////////////
   1352 // * Multiplication
   1353 inline mpreal& mpreal::operator*= (const mpreal& v)
   1354 {
   1355     mpfr_mul(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd());
   1356     MPREAL_MSVC_DEBUGVIEW_CODE;
   1357     return *this;
   1358 }
   1359 
   1360 inline mpreal& mpreal::operator*=(const mpz_t v)
   1361 {
   1362     mpfr_mul_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1363     MPREAL_MSVC_DEBUGVIEW_CODE;
   1364     return *this;
   1365 }
   1366 
   1367 inline mpreal& mpreal::operator*=(const mpq_t v)
   1368 {
   1369     mpfr_mul_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1370     MPREAL_MSVC_DEBUGVIEW_CODE;
   1371     return *this;
   1372 }
   1373 
   1374 inline mpreal& mpreal::operator*=(const long double v)
   1375 {
   1376     *this *= mpreal(v);
   1377     MPREAL_MSVC_DEBUGVIEW_CODE;
   1378     return *this;
   1379 }
   1380 
   1381 inline mpreal& mpreal::operator*=(const double v)
   1382 {
   1383 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
   1384     mpfr_mul_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1385 #else
   1386     *this *= mpreal(v);
   1387 #endif
   1388     MPREAL_MSVC_DEBUGVIEW_CODE;
   1389     return *this;
   1390 }
   1391 
   1392 inline mpreal& mpreal::operator*=(const unsigned long int v)
   1393 {
   1394     mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1395     MPREAL_MSVC_DEBUGVIEW_CODE;
   1396     return *this;
   1397 }
   1398 
   1399 inline mpreal& mpreal::operator*=(const unsigned int v)
   1400 {
   1401     mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1402     MPREAL_MSVC_DEBUGVIEW_CODE;
   1403     return *this;
   1404 }
   1405 
   1406 inline mpreal& mpreal::operator*=(const long int v)
   1407 {
   1408     mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1409     MPREAL_MSVC_DEBUGVIEW_CODE;
   1410     return *this;
   1411 }
   1412 
   1413 inline mpreal& mpreal::operator*=(const int v)
   1414 {
   1415     mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1416     MPREAL_MSVC_DEBUGVIEW_CODE;
   1417     return *this;
   1418 }
   1419 
   1420 inline const mpreal operator*(const mpreal& a, const mpreal& b)
   1421 {
   1422   mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr())));
   1423   mpfr_mul(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd());
   1424   return c;
   1425 }
   1426 
   1427 //////////////////////////////////////////////////////////////////////////
   1428 // / Division
   1429 inline mpreal& mpreal::operator/=(const mpreal& v)
   1430 {
   1431     mpfr_div(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd());
   1432     MPREAL_MSVC_DEBUGVIEW_CODE;
   1433     return *this;
   1434 }
   1435 
   1436 inline mpreal& mpreal::operator/=(const mpz_t v)
   1437 {
   1438     mpfr_div_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1439     MPREAL_MSVC_DEBUGVIEW_CODE;
   1440     return *this;
   1441 }
   1442 
   1443 inline mpreal& mpreal::operator/=(const mpq_t v)
   1444 {
   1445     mpfr_div_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1446     MPREAL_MSVC_DEBUGVIEW_CODE;
   1447     return *this;
   1448 }
   1449 
   1450 inline mpreal& mpreal::operator/=(const long double v)
   1451 {
   1452     *this /= mpreal(v);
   1453     MPREAL_MSVC_DEBUGVIEW_CODE;
   1454     return *this;
   1455 }
   1456 
   1457 inline mpreal& mpreal::operator/=(const double v)
   1458 {
   1459 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
   1460     mpfr_div_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1461 #else
   1462     *this /= mpreal(v);
   1463 #endif
   1464     MPREAL_MSVC_DEBUGVIEW_CODE;
   1465     return *this;
   1466 }
   1467 
   1468 inline mpreal& mpreal::operator/=(const unsigned long int v)
   1469 {
   1470     mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1471     MPREAL_MSVC_DEBUGVIEW_CODE;
   1472     return *this;
   1473 }
   1474 
   1475 inline mpreal& mpreal::operator/=(const unsigned int v)
   1476 {
   1477     mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1478     MPREAL_MSVC_DEBUGVIEW_CODE;
   1479     return *this;
   1480 }
   1481 
   1482 inline mpreal& mpreal::operator/=(const long int v)
   1483 {
   1484     mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1485     MPREAL_MSVC_DEBUGVIEW_CODE;
   1486     return *this;
   1487 }
   1488 
   1489 inline mpreal& mpreal::operator/=(const int v)
   1490 {
   1491     mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd());
   1492     MPREAL_MSVC_DEBUGVIEW_CODE;
   1493     return *this;
   1494 }
   1495 
   1496 inline const mpreal operator/(const mpreal& a, const mpreal& b)
   1497 {
   1498   mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_srcptr()), mpfr_get_prec(b.mpfr_srcptr())));
   1499   mpfr_div(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd());
   1500   return c;
   1501 }
   1502 
   1503 inline const mpreal operator/(const unsigned long int b, const mpreal& a)
   1504 {
   1505     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
   1506     mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1507     return x;
   1508 }
   1509 
   1510 inline const mpreal operator/(const unsigned int b, const mpreal& a)
   1511 {
   1512     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
   1513     mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1514     return x;
   1515 }
   1516 
   1517 inline const mpreal operator/(const long int b, const mpreal& a)
   1518 {
   1519     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
   1520     mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1521     return x;
   1522 }
   1523 
   1524 inline const mpreal operator/(const int b, const mpreal& a)
   1525 {
   1526     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
   1527     mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1528     return x;
   1529 }
   1530 
   1531 inline const mpreal operator/(const double  b, const mpreal& a)
   1532 {
   1533 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
   1534     mpreal x(0, mpfr_get_prec(a.mpfr_srcptr()));
   1535     mpfr_d_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd());
   1536     return x;
   1537 #else
   1538     mpreal x(0, mpfr_get_prec(a.mpfr_ptr()));
   1539     x /= a;
   1540     return x;
   1541 #endif
   1542 }
   1543 
   1544 //////////////////////////////////////////////////////////////////////////
   1545 // Shifts operators - Multiplication/Division by power of 2
   1546 inline mpreal& mpreal::operator<<=(const unsigned long int u)
   1547 {
   1548     mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1549     MPREAL_MSVC_DEBUGVIEW_CODE;
   1550     return *this;
   1551 }
   1552 
   1553 inline mpreal& mpreal::operator<<=(const unsigned int u)
   1554 {
   1555     mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast<unsigned long int>(u),mpreal::get_default_rnd());
   1556     MPREAL_MSVC_DEBUGVIEW_CODE;
   1557     return *this;
   1558 }
   1559 
   1560 inline mpreal& mpreal::operator<<=(const long int u)
   1561 {
   1562     mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1563     MPREAL_MSVC_DEBUGVIEW_CODE;
   1564     return *this;
   1565 }
   1566 
   1567 inline mpreal& mpreal::operator<<=(const int u)
   1568 {
   1569     mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),static_cast<long int>(u),mpreal::get_default_rnd());
   1570     MPREAL_MSVC_DEBUGVIEW_CODE;
   1571     return *this;
   1572 }
   1573 
   1574 inline mpreal& mpreal::operator>>=(const unsigned long int u)
   1575 {
   1576     mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1577     MPREAL_MSVC_DEBUGVIEW_CODE;
   1578     return *this;
   1579 }
   1580 
   1581 inline mpreal& mpreal::operator>>=(const unsigned int u)
   1582 {
   1583     mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast<unsigned long int>(u),mpreal::get_default_rnd());
   1584     MPREAL_MSVC_DEBUGVIEW_CODE;
   1585     return *this;
   1586 }
   1587 
   1588 inline mpreal& mpreal::operator>>=(const long int u)
   1589 {
   1590     mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd());
   1591     MPREAL_MSVC_DEBUGVIEW_CODE;
   1592     return *this;
   1593 }
   1594 
   1595 inline mpreal& mpreal::operator>>=(const int u)
   1596 {
   1597     mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),static_cast<long int>(u),mpreal::get_default_rnd());
   1598     MPREAL_MSVC_DEBUGVIEW_CODE;
   1599     return *this;
   1600 }
   1601 
   1602 inline const mpreal operator<<(const mpreal& v, const unsigned long int k)
   1603 {
   1604     return mul_2ui(v,k);
   1605 }
   1606 
   1607 inline const mpreal operator<<(const mpreal& v, const unsigned int k)
   1608 {
   1609     return mul_2ui(v,static_cast<unsigned long int>(k));
   1610 }
   1611 
   1612 inline const mpreal operator<<(const mpreal& v, const long int k)
   1613 {
   1614     return mul_2si(v,k);
   1615 }
   1616 
   1617 inline const mpreal operator<<(const mpreal& v, const int k)
   1618 {
   1619     return mul_2si(v,static_cast<long int>(k));
   1620 }
   1621 
   1622 inline const mpreal operator>>(const mpreal& v, const unsigned long int k)
   1623 {
   1624     return div_2ui(v,k);
   1625 }
   1626 
   1627 inline const mpreal operator>>(const mpreal& v, const long int k)
   1628 {
   1629     return div_2si(v,k);
   1630 }
   1631 
   1632 inline const mpreal operator>>(const mpreal& v, const unsigned int k)
   1633 {
   1634     return div_2ui(v,static_cast<unsigned long int>(k));
   1635 }
   1636 
   1637 inline const mpreal operator>>(const mpreal& v, const int k)
   1638 {
   1639     return div_2si(v,static_cast<long int>(k));
   1640 }
   1641 
   1642 // mul_2ui
   1643 inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
   1644 {
   1645     mpreal x(v);
   1646     mpfr_mul_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode);
   1647     return x;
   1648 }
   1649 
   1650 // mul_2si
   1651 inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode)
   1652 {
   1653     mpreal x(v);
   1654     mpfr_mul_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode);
   1655     return x;
   1656 }
   1657 
   1658 inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
   1659 {
   1660     mpreal x(v);
   1661     mpfr_div_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode);
   1662     return x;
   1663 }
   1664 
   1665 inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode)
   1666 {
   1667     mpreal x(v);
   1668     mpfr_div_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode);
   1669     return x;
   1670 }
   1671 
   1672 //////////////////////////////////////////////////////////////////////////
   1673 //Boolean operators
   1674 inline bool operator >  (const mpreal& a, const mpreal& b){    return (mpfr_greater_p       (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
   1675 inline bool operator >= (const mpreal& a, const mpreal& b){    return (mpfr_greaterequal_p  (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
   1676 inline bool operator <  (const mpreal& a, const mpreal& b){    return (mpfr_less_p          (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
   1677 inline bool operator <= (const mpreal& a, const mpreal& b){    return (mpfr_lessequal_p     (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
   1678 inline bool operator == (const mpreal& a, const mpreal& b){    return (mpfr_equal_p         (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
   1679 inline bool operator != (const mpreal& a, const mpreal& b){    return (mpfr_lessgreater_p   (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 );    }
   1680 
   1681 inline bool operator == (const mpreal& a, const unsigned long int b ){    return (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 );    }
   1682 inline bool operator == (const mpreal& a, const unsigned int b      ){    return (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 );    }
   1683 inline bool operator == (const mpreal& a, const long int b          ){    return (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 );    }
   1684 inline bool operator == (const mpreal& a, const int b               ){    return (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 );    }
   1685 inline bool operator == (const mpreal& a, const long double b       ){    return (mpfr_cmp_ld(a.mpfr_srcptr(),b) == 0 );    }
   1686 inline bool operator == (const mpreal& a, const double b            ){    return (mpfr_cmp_d (a.mpfr_srcptr(),b) == 0 );    }
   1687 
   1688 
   1689 inline bool isnan    (const mpreal& op){    return (mpfr_nan_p    (op.mpfr_srcptr()) != 0 );    }
   1690 inline bool isinf    (const mpreal& op){    return (mpfr_inf_p    (op.mpfr_srcptr()) != 0 );    }
   1691 inline bool isfinite (const mpreal& op){    return (mpfr_number_p (op.mpfr_srcptr()) != 0 );    }
   1692 inline bool iszero   (const mpreal& op){    return (mpfr_zero_p   (op.mpfr_srcptr()) != 0 );    }
   1693 inline bool isint    (const mpreal& op){    return (mpfr_integer_p(op.mpfr_srcptr()) != 0 );    }
   1694 
   1695 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
   1696 inline bool isregular(const mpreal& op){    return (mpfr_regular_p(op.mpfr_srcptr()));}
   1697 #endif
   1698 
   1699 //////////////////////////////////////////////////////////////////////////
   1700 // Type Converters
   1701 inline bool             mpreal::toBool (mp_rnd_t /*mode*/) const   {    return  mpfr_zero_p (mpfr_srcptr()) == 0;     }
   1702 inline long             mpreal::toLong   (mp_rnd_t mode)  const    {    return  mpfr_get_si (mpfr_srcptr(), mode);    }
   1703 inline unsigned long    mpreal::toULong  (mp_rnd_t mode)  const    {    return  mpfr_get_ui (mpfr_srcptr(), mode);    }
   1704 inline float            mpreal::toFloat  (mp_rnd_t mode)  const    {    return  mpfr_get_flt(mpfr_srcptr(), mode);    }
   1705 inline double           mpreal::toDouble (mp_rnd_t mode)  const    {    return  mpfr_get_d  (mpfr_srcptr(), mode);    }
   1706 inline long double      mpreal::toLDouble(mp_rnd_t mode)  const    {    return  mpfr_get_ld (mpfr_srcptr(), mode);    }
   1707 
   1708 #if defined (MPREAL_HAVE_INT64_SUPPORT)
   1709 inline int64_t      mpreal::toInt64 (mp_rnd_t mode)    const{    return mpfr_get_sj(mpfr_srcptr(), mode);    }
   1710 inline uint64_t     mpreal::toUInt64(mp_rnd_t mode)    const{    return mpfr_get_uj(mpfr_srcptr(), mode);    }
   1711 #endif
   1712 
   1713 inline ::mpfr_ptr     mpreal::mpfr_ptr()             { return mp; }
   1714 inline ::mpfr_srcptr  mpreal::mpfr_ptr()    const    { return mp; }
   1715 inline ::mpfr_srcptr  mpreal::mpfr_srcptr() const    { return mp; }
   1716 
   1717 template <class T>
   1718 inline std::string toString(T t, std::ios_base & (*f)(std::ios_base&))
   1719 {
   1720     std::ostringstream oss;
   1721     oss << f << t;
   1722     return oss.str();
   1723 }
   1724 
   1725 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
   1726 
   1727 inline std::string mpreal::toString(const std::string& format) const
   1728 {
   1729     char *s = NULL;
   1730     std::string out;
   1731 
   1732     if( !format.empty() )
   1733     {
   1734         if(!(mpfr_asprintf(&s, format.c_str(), mpfr_srcptr()) < 0))
   1735         {
   1736             out = std::string(s);
   1737 
   1738             mpfr_free_str(s);
   1739         }
   1740     }
   1741 
   1742     return out;
   1743 }
   1744 
   1745 #endif
   1746 
   1747 inline std::string mpreal::toString(int n, int b, mp_rnd_t mode) const
   1748 {
   1749     // TODO: Add extended format specification (f, e, rounding mode) as it done in output operator
   1750     (void)b;
   1751     (void)mode;
   1752 
   1753 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
   1754 
   1755     std::ostringstream format;
   1756 
   1757     int digits = (n >= 0) ? n : bits2digits(mpfr_get_prec(mpfr_srcptr()));
   1758 
   1759     format << "%." << digits << "RNg";
   1760 
   1761     return toString(format.str());
   1762 
   1763 #else
   1764 
   1765     char *s, *ns = NULL;
   1766     size_t slen, nslen;
   1767     mp_exp_t exp;
   1768     std::string out;
   1769 
   1770     if(mpfr_inf_p(mp))
   1771     {
   1772         if(mpfr_sgn(mp)>0) return "+Inf";
   1773         else               return "-Inf";
   1774     }
   1775 
   1776     if(mpfr_zero_p(mp)) return "0";
   1777     if(mpfr_nan_p(mp))  return "NaN";
   1778 
   1779     s  = mpfr_get_str(NULL, &exp, b, 0, mp, mode);
   1780     ns = mpfr_get_str(NULL, &exp, b, (std::max)(0,n), mp, mode);
   1781 
   1782     if(s!=NULL && ns!=NULL)
   1783     {
   1784         slen  = strlen(s);
   1785         nslen = strlen(ns);
   1786         if(nslen<=slen)
   1787         {
   1788             mpfr_free_str(s);
   1789             s = ns;
   1790             slen = nslen;
   1791         }
   1792         else {
   1793             mpfr_free_str(ns);
   1794         }
   1795 
   1796         // Make human eye-friendly formatting if possible
   1797         if (exp>0 && static_cast<size_t>(exp)<slen)
   1798         {
   1799             if(s[0]=='-')
   1800             {
   1801                 // Remove zeros starting from right end
   1802                 char* ptr = s+slen-1;
   1803                 while (*ptr=='0' && ptr>s+exp) ptr--;
   1804 
   1805                 if(ptr==s+exp) out = std::string(s,exp+1);
   1806                 else           out = std::string(s,exp+1)+'.'+std::string(s+exp+1,ptr-(s+exp+1)+1);
   1807 
   1808                 //out = string(s,exp+1)+'.'+string(s+exp+1);
   1809             }
   1810             else
   1811             {
   1812                 // Remove zeros starting from right end
   1813                 char* ptr = s+slen-1;
   1814                 while (*ptr=='0' && ptr>s+exp-1) ptr--;
   1815 
   1816                 if(ptr==s+exp-1) out = std::string(s,exp);
   1817                 else             out = std::string(s,exp)+'.'+std::string(s+exp,ptr-(s+exp)+1);
   1818 
   1819                 //out = string(s,exp)+'.'+string(s+exp);
   1820             }
   1821 
   1822         }else{ // exp<0 || exp>slen
   1823             if(s[0]=='-')
   1824             {
   1825                 // Remove zeros starting from right end
   1826                 char* ptr = s+slen-1;
   1827                 while (*ptr=='0' && ptr>s+1) ptr--;
   1828 
   1829                 if(ptr==s+1) out = std::string(s,2);
   1830                 else         out = std::string(s,2)+'.'+std::string(s+2,ptr-(s+2)+1);
   1831 
   1832                 //out = string(s,2)+'.'+string(s+2);
   1833             }
   1834             else
   1835             {
   1836                 // Remove zeros starting from right end
   1837                 char* ptr = s+slen-1;
   1838                 while (*ptr=='0' && ptr>s) ptr--;
   1839 
   1840                 if(ptr==s) out = std::string(s,1);
   1841                 else       out = std::string(s,1)+'.'+std::string(s+1,ptr-(s+1)+1);
   1842 
   1843                 //out = string(s,1)+'.'+string(s+1);
   1844             }
   1845 
   1846             // Make final string
   1847             if(--exp)
   1848             {
   1849                 if(exp>0) out += "e+"+mpfr::toString<mp_exp_t>(exp,std::dec);
   1850                 else       out += "e"+mpfr::toString<mp_exp_t>(exp,std::dec);
   1851             }
   1852         }
   1853 
   1854         mpfr_free_str(s);
   1855         return out;
   1856     }else{
   1857         return "conversion error!";
   1858     }
   1859 #endif
   1860 }
   1861 
   1862 
   1863 //////////////////////////////////////////////////////////////////////////
   1864 // I/O
   1865 inline std::ostream& mpreal::output(std::ostream& os) const
   1866 {
   1867     std::ostringstream format;
   1868     const std::ios::fmtflags flags = os.flags();
   1869 
   1870     format << ((flags & std::ios::showpos) ? "%+" : "%");
   1871     if (os.precision() >= 0)
   1872         format << '.' << os.precision() << "R*"
   1873                << ((flags & std::ios::floatfield) == std::ios::fixed ? 'f' :
   1874                    (flags & std::ios::floatfield) == std::ios::scientific ? 'e' :
   1875                    'g');
   1876     else
   1877         format << "R*e";
   1878 
   1879     char *s = NULL;
   1880     if(!(mpfr_asprintf(&s, format.str().c_str(),
   1881                         mpfr::mpreal::get_default_rnd(),
   1882                         mpfr_srcptr())
   1883         < 0))
   1884     {
   1885         os << std::string(s);
   1886         mpfr_free_str(s);
   1887     }
   1888     return os;
   1889 }
   1890 
   1891 inline std::ostream& operator<<(std::ostream& os, const mpreal& v)
   1892 {
   1893     return v.output(os);
   1894 }
   1895 
   1896 inline std::istream& operator>>(std::istream &is, mpreal& v)
   1897 {
   1898     // TODO: use cout::hexfloat and other flags to setup base
   1899     std::string tmp;
   1900     is >> tmp;
   1901     mpfr_set_str(v.mpfr_ptr(), tmp.c_str(), 10, mpreal::get_default_rnd());
   1902     return is;
   1903 }
   1904 
   1905 //////////////////////////////////////////////////////////////////////////
   1906 //     Bits - decimal digits relation
   1907 //        bits   = ceil(digits*log[2](10))
   1908 //        digits = floor(bits*log[10](2))
   1909 
   1910 inline mp_prec_t digits2bits(int d)
   1911 {
   1912     const double LOG2_10 = 3.3219280948873624;
   1913 
   1914     return mp_prec_t(std::ceil( d * LOG2_10 ));
   1915 }
   1916 
   1917 inline int bits2digits(mp_prec_t b)
   1918 {
   1919     const double LOG10_2 = 0.30102999566398119;
   1920 
   1921     return int(std::floor( b * LOG10_2 ));
   1922 }
   1923 
   1924 //////////////////////////////////////////////////////////////////////////
   1925 // Set/Get number properties
   1926 inline int sgn(const mpreal& op)
   1927 {
   1928     int r = mpfr_signbit(op.mpfr_srcptr());
   1929     return (r > 0? -1 : 1);
   1930 }
   1931 
   1932 inline mpreal& mpreal::setSign(int sign, mp_rnd_t RoundingMode)
   1933 {
   1934     mpfr_setsign(mpfr_ptr(), mpfr_srcptr(), (sign < 0 ? 1 : 0), RoundingMode);
   1935     MPREAL_MSVC_DEBUGVIEW_CODE;
   1936     return *this;
   1937 }
   1938 
   1939 inline int mpreal::getPrecision() const
   1940 {
   1941     return int(mpfr_get_prec(mpfr_srcptr()));
   1942 }
   1943 
   1944 inline mpreal& mpreal::setPrecision(int Precision, mp_rnd_t RoundingMode)
   1945 {
   1946     mpfr_prec_round(mpfr_ptr(), Precision, RoundingMode);
   1947     MPREAL_MSVC_DEBUGVIEW_CODE;
   1948     return *this;
   1949 }
   1950 
   1951 inline mpreal& mpreal::setInf(int sign)
   1952 {
   1953     mpfr_set_inf(mpfr_ptr(), sign);
   1954     MPREAL_MSVC_DEBUGVIEW_CODE;
   1955     return *this;
   1956 }
   1957 
   1958 inline mpreal& mpreal::setNan()
   1959 {
   1960     mpfr_set_nan(mpfr_ptr());
   1961     MPREAL_MSVC_DEBUGVIEW_CODE;
   1962     return *this;
   1963 }
   1964 
   1965 inline mpreal&    mpreal::setZero(int sign)
   1966 {
   1967 
   1968 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
   1969     mpfr_set_zero(mpfr_ptr(), sign);
   1970 #else
   1971     mpfr_set_si(mpfr_ptr(), 0, (mpfr_get_default_rounding_mode)());
   1972     setSign(sign);
   1973 #endif
   1974 
   1975     MPREAL_MSVC_DEBUGVIEW_CODE;
   1976     return *this;
   1977 }
   1978 
   1979 inline mp_prec_t mpreal::get_prec() const
   1980 {
   1981     return mpfr_get_prec(mpfr_srcptr());
   1982 }
   1983 
   1984 inline void mpreal::set_prec(mp_prec_t prec, mp_rnd_t rnd_mode)
   1985 {
   1986     mpfr_prec_round(mpfr_ptr(),prec,rnd_mode);
   1987     MPREAL_MSVC_DEBUGVIEW_CODE;
   1988 }
   1989 
   1990 inline mp_exp_t mpreal::get_exp ()
   1991 {
   1992     return mpfr_get_exp(mpfr_srcptr());
   1993 }
   1994 
   1995 inline int mpreal::set_exp (mp_exp_t e)
   1996 {
   1997     int x = mpfr_set_exp(mpfr_ptr(), e);
   1998     MPREAL_MSVC_DEBUGVIEW_CODE;
   1999     return x;
   2000 }
   2001 
   2002 inline const mpreal frexp(const mpreal& v, mp_exp_t* exp)
   2003 {
   2004     mpreal x(v);
   2005     *exp = x.get_exp();
   2006     x.set_exp(0);
   2007     return x;
   2008 }
   2009 
   2010 inline const mpreal ldexp(const mpreal& v, mp_exp_t exp)
   2011 {
   2012     mpreal x(v);
   2013 
   2014     // rounding is not important since we just increasing the exponent
   2015     mpfr_mul_2si(x.mpfr_ptr(), x.mpfr_srcptr(), exp, mpreal::get_default_rnd());
   2016     return x;
   2017 }
   2018 
   2019 inline mpreal machine_epsilon(mp_prec_t prec)
   2020 {
   2021     /* the smallest eps such that 1 + eps != 1 */
   2022     return machine_epsilon(mpreal(1, prec));
   2023 }
   2024 
   2025 inline mpreal machine_epsilon(const mpreal& x)
   2026 {
   2027     /* the smallest eps such that x + eps != x */
   2028     if( x < 0)
   2029     {
   2030         return nextabove(-x) + x;
   2031     }else{
   2032         return nextabove( x) - x;
   2033     }
   2034 }
   2035 
   2036 // minval is 'safe' meaning 1 / minval does not overflow
   2037 inline mpreal minval(mp_prec_t prec)
   2038 {
   2039     /* min = 1/2 * 2^emin = 2^(emin - 1) */
   2040     return mpreal(1, prec) << mpreal::get_emin()-1;
   2041 }
   2042 
   2043 // maxval is 'safe' meaning 1 / maxval does not underflow
   2044 inline mpreal maxval(mp_prec_t prec)
   2045 {
   2046     /* max = (1 - eps) * 2^emax, eps is machine epsilon */
   2047     return (mpreal(1, prec) - machine_epsilon(prec)) << mpreal::get_emax();
   2048 }
   2049 
   2050 inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps)
   2051 {
   2052     return abs(a - b) <= machine_epsilon((max)(abs(a), abs(b))) * maxUlps;
   2053 }
   2054 
   2055 inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps)
   2056 {
   2057     return abs(a - b) <= eps;
   2058 }
   2059 
   2060 inline bool isEqualFuzzy(const mpreal& a, const mpreal& b)
   2061 {
   2062     return isEqualFuzzy(a, b, machine_epsilon((max)(1, (min)(abs(a), abs(b)))));
   2063 }
   2064 
   2065 inline const mpreal modf(const mpreal& v, mpreal& n)
   2066 {
   2067     mpreal f(v);
   2068 
   2069     // rounding is not important since we are using the same number
   2070     mpfr_frac (f.mpfr_ptr(),f.mpfr_srcptr(),mpreal::get_default_rnd());
   2071     mpfr_trunc(n.mpfr_ptr(),v.mpfr_srcptr());
   2072     return f;
   2073 }
   2074 
   2075 inline int mpreal::check_range (int t, mp_rnd_t rnd_mode)
   2076 {
   2077     return mpfr_check_range(mpfr_ptr(),t,rnd_mode);
   2078 }
   2079 
   2080 inline int mpreal::subnormalize (int t,mp_rnd_t rnd_mode)
   2081 {
   2082     int r = mpfr_subnormalize(mpfr_ptr(),t,rnd_mode);
   2083     MPREAL_MSVC_DEBUGVIEW_CODE;
   2084     return r;
   2085 }
   2086 
   2087 inline mp_exp_t mpreal::get_emin (void)
   2088 {
   2089     return mpfr_get_emin();
   2090 }
   2091 
   2092 inline int mpreal::set_emin (mp_exp_t exp)
   2093 {
   2094     return mpfr_set_emin(exp);
   2095 }
   2096 
   2097 inline mp_exp_t mpreal::get_emax (void)
   2098 {
   2099     return mpfr_get_emax();
   2100 }
   2101 
   2102 inline int mpreal::set_emax (mp_exp_t exp)
   2103 {
   2104     return mpfr_set_emax(exp);
   2105 }
   2106 
   2107 inline mp_exp_t mpreal::get_emin_min (void)
   2108 {
   2109     return mpfr_get_emin_min();
   2110 }
   2111 
   2112 inline mp_exp_t mpreal::get_emin_max (void)
   2113 {
   2114     return mpfr_get_emin_max();
   2115 }
   2116 
   2117 inline mp_exp_t mpreal::get_emax_min (void)
   2118 {
   2119     return mpfr_get_emax_min();
   2120 }
   2121 
   2122 inline mp_exp_t mpreal::get_emax_max (void)
   2123 {
   2124     return mpfr_get_emax_max();
   2125 }
   2126 
   2127 //////////////////////////////////////////////////////////////////////////
   2128 // Mathematical Functions
   2129 //////////////////////////////////////////////////////////////////////////
   2130 #define MPREAL_UNARY_MATH_FUNCTION_BODY(f)                    \
   2131         mpreal y(0, mpfr_get_prec(x.mpfr_srcptr()));          \
   2132         mpfr_##f(y.mpfr_ptr(), x.mpfr_srcptr(), r);           \
   2133         return y;
   2134 
   2135 inline const mpreal sqr  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd())
   2136 {   MPREAL_UNARY_MATH_FUNCTION_BODY(sqr );    }
   2137 
   2138 inline const mpreal sqrt (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd())
   2139 {   MPREAL_UNARY_MATH_FUNCTION_BODY(sqrt);    }
   2140 
   2141 inline const mpreal sqrt(const unsigned long int x, mp_rnd_t r)
   2142 {
   2143     mpreal y;
   2144     mpfr_sqrt_ui(y.mpfr_ptr(), x, r);
   2145     return y;
   2146 }
   2147 
   2148 inline const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode)
   2149 {
   2150     return sqrt(static_cast<unsigned long int>(v),rnd_mode);
   2151 }
   2152 
   2153 inline const mpreal sqrt(const long int v, mp_rnd_t rnd_mode)
   2154 {
   2155     if (v>=0)   return sqrt(static_cast<unsigned long int>(v),rnd_mode);
   2156     else        return mpreal().setNan(); // NaN
   2157 }
   2158 
   2159 inline const mpreal sqrt(const int v, mp_rnd_t rnd_mode)
   2160 {
   2161     if (v>=0)   return sqrt(static_cast<unsigned long int>(v),rnd_mode);
   2162     else        return mpreal().setNan(); // NaN
   2163 }
   2164 
   2165 inline const mpreal root(const mpreal& x, unsigned long int k, mp_rnd_t r = mpreal::get_default_rnd())
   2166 {
   2167     mpreal y(0, mpfr_get_prec(x.mpfr_srcptr()));
   2168     mpfr_root(y.mpfr_ptr(), x.mpfr_srcptr(), k, r);
   2169     return y;
   2170 }
   2171 
   2172 inline const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t r = mpreal::get_default_rnd())
   2173 {
   2174     mpreal y(0, mpfr_get_prec(a.mpfr_srcptr()));
   2175     mpfr_dim(y.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), r);
   2176     return y;
   2177 }
   2178 
   2179 inline int cmpabs(const mpreal& a,const mpreal& b)
   2180 {
   2181     return mpfr_cmpabs(a.mpfr_ptr(), b.mpfr_srcptr());
   2182 }
   2183 
   2184 inline int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2185 {
   2186     return mpfr_sin_cos(s.mpfr_ptr(), c.mpfr_ptr(), v.mpfr_srcptr(), rnd_mode);
   2187 }
   2188 
   2189 inline const mpreal sqrt  (const long double v, mp_rnd_t rnd_mode)    {   return sqrt(mpreal(v),rnd_mode);    }
   2190 inline const mpreal sqrt  (const double v, mp_rnd_t rnd_mode)         {   return sqrt(mpreal(v),rnd_mode);    }
   2191 
   2192 inline const mpreal cbrt  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(cbrt );    }
   2193 inline const mpreal fabs  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(abs  );    }
   2194 inline const mpreal abs   (const mpreal& x, mp_rnd_t r)                             {   MPREAL_UNARY_MATH_FUNCTION_BODY(abs  );    }
   2195 inline const mpreal log   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(log  );    }
   2196 inline const mpreal log2  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(log2 );    }
   2197 inline const mpreal log10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(log10);    }
   2198 inline const mpreal exp   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(exp  );    }
   2199 inline const mpreal exp2  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(exp2 );    }
   2200 inline const mpreal exp10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(exp10);    }
   2201 inline const mpreal cos   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(cos  );    }
   2202 inline const mpreal sin   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(sin  );    }
   2203 inline const mpreal tan   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(tan  );    }
   2204 inline const mpreal sec   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(sec  );    }
   2205 inline const mpreal csc   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(csc  );    }
   2206 inline const mpreal cot   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(cot  );    }
   2207 inline const mpreal acos  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(acos );    }
   2208 inline const mpreal asin  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(asin );    }
   2209 inline const mpreal atan  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(atan );    }
   2210 
   2211 inline const mpreal acot  (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return atan (1/v, r);                      }
   2212 inline const mpreal asec  (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return acos (1/v, r);                      }
   2213 inline const mpreal acsc  (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return asin (1/v, r);                      }
   2214 inline const mpreal acoth (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return atanh(1/v, r);                      }
   2215 inline const mpreal asech (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return acosh(1/v, r);                      }
   2216 inline const mpreal acsch (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) {   return asinh(1/v, r);                      }
   2217 
   2218 inline const mpreal cosh  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(cosh );    }
   2219 inline const mpreal sinh  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(sinh );    }
   2220 inline const mpreal tanh  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(tanh );    }
   2221 inline const mpreal sech  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(sech );    }
   2222 inline const mpreal csch  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(csch );    }
   2223 inline const mpreal coth  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(coth );    }
   2224 inline const mpreal acosh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(acosh);    }
   2225 inline const mpreal asinh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(asinh);    }
   2226 inline const mpreal atanh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(atanh);    }
   2227 
   2228 inline const mpreal log1p   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(log1p  );    }
   2229 inline const mpreal expm1   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(expm1  );    }
   2230 inline const mpreal eint    (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(eint   );    }
   2231 inline const mpreal gamma   (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(gamma  );    }
   2232 inline const mpreal lngamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(lngamma);    }
   2233 inline const mpreal zeta    (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(zeta   );    }
   2234 inline const mpreal erf     (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(erf    );    }
   2235 inline const mpreal erfc    (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(erfc   );    }
   2236 inline const mpreal besselj0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(j0     );    }
   2237 inline const mpreal besselj1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(j1     );    }
   2238 inline const mpreal bessely0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(y0     );    }
   2239 inline const mpreal bessely1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(y1     );    }
   2240 
   2241 inline const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2242 {
   2243     mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision()));
   2244     mpfr_atan2(a.mpfr_ptr(), y.mpfr_srcptr(), x.mpfr_srcptr(), rnd_mode);
   2245     return a;
   2246 }
   2247 
   2248 inline const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2249 {
   2250     mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision()));
   2251     mpfr_hypot(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode);
   2252     return a;
   2253 }
   2254 
   2255 inline const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2256 {
   2257     mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision()));
   2258     mpfr_remainder(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode);
   2259     return a;
   2260 }
   2261 
   2262 inline const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2263 {
   2264     mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision()));
   2265     mpfr_remquo(a.mpfr_ptr(),q, x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode);
   2266     return a;
   2267 }
   2268 
   2269 inline const mpreal fac_ui (unsigned long int v, mp_prec_t prec     = mpreal::get_default_prec(),
   2270                                            mp_rnd_t  rnd_mode = mpreal::get_default_rnd())
   2271 {
   2272     mpreal x(0, prec);
   2273     mpfr_fac_ui(x.mpfr_ptr(),v,rnd_mode);
   2274     return x;
   2275 }
   2276 
   2277 
   2278 inline const mpreal lgamma (const mpreal& v, int *signp = 0, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2279 {
   2280     mpreal x(v);
   2281     int tsignp;
   2282 
   2283     if(signp)   mpfr_lgamma(x.mpfr_ptr(),  signp,v.mpfr_srcptr(),rnd_mode);
   2284     else        mpfr_lgamma(x.mpfr_ptr(),&tsignp,v.mpfr_srcptr(),rnd_mode);
   2285 
   2286     return x;
   2287 }
   2288 
   2289 
   2290 inline const mpreal besseljn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd())
   2291 {
   2292     mpreal  y(0, x.getPrecision());
   2293     mpfr_jn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r);
   2294     return y;
   2295 }
   2296 
   2297 inline const mpreal besselyn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd())
   2298 {
   2299     mpreal  y(0, x.getPrecision());
   2300     mpfr_yn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r);
   2301     return y;
   2302 }
   2303 
   2304 inline const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2305 {
   2306     mpreal a;
   2307     mp_prec_t p1, p2, p3;
   2308 
   2309     p1 = v1.get_prec();
   2310     p2 = v2.get_prec();
   2311     p3 = v3.get_prec();
   2312 
   2313     a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
   2314 
   2315     mpfr_fma(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
   2316     return a;
   2317 }
   2318 
   2319 inline const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2320 {
   2321     mpreal a;
   2322     mp_prec_t p1, p2, p3;
   2323 
   2324     p1 = v1.get_prec();
   2325     p2 = v2.get_prec();
   2326     p3 = v3.get_prec();
   2327 
   2328     a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
   2329 
   2330     mpfr_fms(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
   2331     return a;
   2332 }
   2333 
   2334 inline const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2335 {
   2336     mpreal a;
   2337     mp_prec_t p1, p2;
   2338 
   2339     p1 = v1.get_prec();
   2340     p2 = v2.get_prec();
   2341 
   2342     a.set_prec(p1>p2?p1:p2);
   2343 
   2344     mpfr_agm(a.mp, v1.mp, v2.mp, rnd_mode);
   2345 
   2346     return a;
   2347 }
   2348 
   2349 inline const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2350 {
   2351     mpreal x;
   2352     mpfr_ptr* t;
   2353     unsigned long int i;
   2354 
   2355     t = new mpfr_ptr[n];
   2356     for (i=0;i<n;i++) t[i] = (mpfr_ptr)tab[i].mp;
   2357     mpfr_sum(x.mp,t,n,rnd_mode);
   2358     delete[] t;
   2359     return x;
   2360 }
   2361 
   2362 //////////////////////////////////////////////////////////////////////////
   2363 // MPFR 2.4.0 Specifics
   2364 #if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
   2365 
   2366 inline int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2367 {
   2368     return mpfr_sinh_cosh(s.mp,c.mp,v.mp,rnd_mode);
   2369 }
   2370 
   2371 inline const mpreal li2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd())
   2372 {
   2373     MPREAL_UNARY_MATH_FUNCTION_BODY(li2);
   2374 }
   2375 
   2376 inline const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2377 {
   2378     /*  R = rem(X,Y) if Y != 0, returns X - n * Y where n = trunc(X/Y). */
   2379     return fmod(x, y, rnd_mode);
   2380 }
   2381 
   2382 inline const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2383 {
   2384     (void)rnd_mode;
   2385 
   2386     /*
   2387 
   2388     m = mod(x,y) if y != 0, returns x - n*y where n = floor(x/y)
   2389 
   2390     The following are true by convention:
   2391     - mod(x,0) is x
   2392     - mod(x,x) is 0
   2393     - mod(x,y) for x != y and y != 0 has the same sign as y.
   2394 
   2395     */
   2396 
   2397     if(iszero(y)) return x;
   2398     if(x == y) return 0;
   2399 
   2400     mpreal m = x - floor(x / y) * y;
   2401 
   2402     m.setSign(sgn(y)); // make sure result has the same sign as Y
   2403 
   2404     return m;
   2405 }
   2406 
   2407 inline const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2408 {
   2409     mpreal a;
   2410     mp_prec_t yp, xp;
   2411 
   2412     yp = y.get_prec();
   2413     xp = x.get_prec();
   2414 
   2415     a.set_prec(yp>xp?yp:xp);
   2416 
   2417     mpfr_fmod(a.mp, x.mp, y.mp, rnd_mode);
   2418 
   2419     return a;
   2420 }
   2421 
   2422 inline const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2423 {
   2424     mpreal x(v);
   2425     mpfr_rec_sqrt(x.mp,v.mp,rnd_mode);
   2426     return x;
   2427 }
   2428 #endif //  MPFR 2.4.0 Specifics
   2429 
   2430 //////////////////////////////////////////////////////////////////////////
   2431 // MPFR 3.0.0 Specifics
   2432 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
   2433 inline const mpreal digamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(digamma);     }
   2434 inline const mpreal ai      (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(ai);          }
   2435 #endif // MPFR 3.0.0 Specifics
   2436 
   2437 //////////////////////////////////////////////////////////////////////////
   2438 // Constants
   2439 inline const mpreal const_log2 (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd())
   2440 {
   2441     mpreal x(0, p);
   2442     mpfr_const_log2(x.mpfr_ptr(), r);
   2443     return x;
   2444 }
   2445 
   2446 inline const mpreal const_pi (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd())
   2447 {
   2448     mpreal x(0, p);
   2449     mpfr_const_pi(x.mpfr_ptr(), r);
   2450     return x;
   2451 }
   2452 
   2453 inline const mpreal const_euler (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd())
   2454 {
   2455     mpreal x(0, p);
   2456     mpfr_const_euler(x.mpfr_ptr(), r);
   2457     return x;
   2458 }
   2459 
   2460 inline const mpreal const_catalan (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd())
   2461 {
   2462     mpreal x(0, p);
   2463     mpfr_const_catalan(x.mpfr_ptr(), r);
   2464     return x;
   2465 }
   2466 
   2467 inline const mpreal const_infinity (int sign = 1, mp_prec_t p = mpreal::get_default_prec())
   2468 {
   2469     mpreal x(0, p);
   2470     mpfr_set_inf(x.mpfr_ptr(), sign);
   2471     return x;
   2472 }
   2473 
   2474 //////////////////////////////////////////////////////////////////////////
   2475 // Integer Related Functions
   2476 inline const mpreal ceil(const mpreal& v)
   2477 {
   2478     mpreal x(v);
   2479     mpfr_ceil(x.mp,v.mp);
   2480     return x;
   2481 }
   2482 
   2483 inline const mpreal floor(const mpreal& v)
   2484 {
   2485     mpreal x(v);
   2486     mpfr_floor(x.mp,v.mp);
   2487     return x;
   2488 }
   2489 
   2490 inline const mpreal round(const mpreal& v)
   2491 {
   2492     mpreal x(v);
   2493     mpfr_round(x.mp,v.mp);
   2494     return x;
   2495 }
   2496 
   2497 inline const mpreal trunc(const mpreal& v)
   2498 {
   2499     mpreal x(v);
   2500     mpfr_trunc(x.mp,v.mp);
   2501     return x;
   2502 }
   2503 
   2504 inline const mpreal rint       (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint      );     }
   2505 inline const mpreal rint_ceil  (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint_ceil );     }
   2506 inline const mpreal rint_floor (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint_floor);     }
   2507 inline const mpreal rint_round (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint_round);     }
   2508 inline const mpreal rint_trunc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(rint_trunc);     }
   2509 inline const mpreal frac       (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) {   MPREAL_UNARY_MATH_FUNCTION_BODY(frac      );     }
   2510 
   2511 //////////////////////////////////////////////////////////////////////////
   2512 // Miscellaneous Functions
   2513 inline void         swap (mpreal& a, mpreal& b)            {    mpfr_swap(a.mp,b.mp);   }
   2514 inline const mpreal (max)(const mpreal& x, const mpreal& y){    return (x>y?x:y);       }
   2515 inline const mpreal (min)(const mpreal& x, const mpreal& y){    return (x<y?x:y);       }
   2516 
   2517 inline const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2518 {
   2519     mpreal a;
   2520     mpfr_max(a.mp,x.mp,y.mp,rnd_mode);
   2521     return a;
   2522 }
   2523 
   2524 inline const mpreal fmin(const mpreal& x, const mpreal& y,  mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2525 {
   2526     mpreal a;
   2527     mpfr_min(a.mp,x.mp,y.mp,rnd_mode);
   2528     return a;
   2529 }
   2530 
   2531 inline const mpreal nexttoward (const mpreal& x, const mpreal& y)
   2532 {
   2533     mpreal a(x);
   2534     mpfr_nexttoward(a.mp,y.mp);
   2535     return a;
   2536 }
   2537 
   2538 inline const mpreal nextabove  (const mpreal& x)
   2539 {
   2540     mpreal a(x);
   2541     mpfr_nextabove(a.mp);
   2542     return a;
   2543 }
   2544 
   2545 inline const mpreal nextbelow  (const mpreal& x)
   2546 {
   2547     mpreal a(x);
   2548     mpfr_nextbelow(a.mp);
   2549     return a;
   2550 }
   2551 
   2552 inline const mpreal urandomb (gmp_randstate_t& state)
   2553 {
   2554     mpreal x;
   2555     mpfr_urandomb(x.mp,state);
   2556     return x;
   2557 }
   2558 
   2559 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,1,0))
   2560 // use gmp_randinit_default() to init state, gmp_randclear() to clear
   2561 inline const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2562 {
   2563     mpreal x;
   2564     mpfr_urandom(x.mp,state,rnd_mode);
   2565     return x;
   2566 }
   2567 
   2568 inline const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2569 {
   2570     mpreal x;
   2571     mpfr_grandom(x.mp, NULL, state, rnd_mode);
   2572     return x;
   2573 }
   2574 
   2575 #endif
   2576 
   2577 #if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2))
   2578 inline const mpreal random2 (mp_size_t size, mp_exp_t exp)
   2579 {
   2580     mpreal x;
   2581     mpfr_random2(x.mp,size,exp);
   2582     return x;
   2583 }
   2584 #endif
   2585 
   2586 // Uniformly distributed random number generation
   2587 // a = random(seed); <- initialization & first random number generation
   2588 // a = random();     <- next random numbers generation
   2589 // seed != 0
   2590 inline const mpreal random(unsigned int seed = 0)
   2591 {
   2592 
   2593 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
   2594     static gmp_randstate_t state;
   2595     static bool isFirstTime = true;
   2596 
   2597     if(isFirstTime)
   2598     {
   2599         gmp_randinit_default(state);
   2600         gmp_randseed_ui(state,0);
   2601         isFirstTime = false;
   2602     }
   2603 
   2604     if(seed != 0)    gmp_randseed_ui(state,seed);
   2605 
   2606     return mpfr::urandom(state);
   2607 #else
   2608     if(seed != 0)    std::srand(seed);
   2609     return mpfr::mpreal(std::rand()/(double)RAND_MAX);
   2610 #endif
   2611 
   2612 }
   2613 
   2614 #if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
   2615 inline const mpreal grandom(unsigned int seed = 0)
   2616 {
   2617     static gmp_randstate_t state;
   2618     static bool isFirstTime = true;
   2619 
   2620     if(isFirstTime)
   2621     {
   2622         gmp_randinit_default(state);
   2623         gmp_randseed_ui(state,0);
   2624         isFirstTime = false;
   2625     }
   2626 
   2627     if(seed != 0) gmp_randseed_ui(state,seed);
   2628 
   2629     return mpfr::grandom(state);
   2630 }
   2631 #endif
   2632 
   2633 //////////////////////////////////////////////////////////////////////////
   2634 // Set/Get global properties
   2635 inline void mpreal::set_default_prec(mp_prec_t prec)
   2636 {
   2637     mpfr_set_default_prec(prec);
   2638 }
   2639 
   2640 inline void mpreal::set_default_rnd(mp_rnd_t rnd_mode)
   2641 {
   2642     mpfr_set_default_rounding_mode(rnd_mode);
   2643 }
   2644 
   2645 inline bool mpreal::fits_in_bits(double x, int n)
   2646 {
   2647     int i;
   2648     double t;
   2649     return IsInf(x) || (std::modf ( std::ldexp ( std::frexp ( x, &i ), n ), &t ) == 0.0);
   2650 }
   2651 
   2652 inline const mpreal pow(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2653 {
   2654     mpreal x(a);
   2655     mpfr_pow(x.mp,x.mp,b.mp,rnd_mode);
   2656     return x;
   2657 }
   2658 
   2659 inline const mpreal pow(const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2660 {
   2661     mpreal x(a);
   2662     mpfr_pow_z(x.mp,x.mp,b,rnd_mode);
   2663     return x;
   2664 }
   2665 
   2666 inline const mpreal pow(const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2667 {
   2668     mpreal x(a);
   2669     mpfr_pow_ui(x.mp,x.mp,b,rnd_mode);
   2670     return x;
   2671 }
   2672 
   2673 inline const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode)
   2674 {
   2675     return pow(a,static_cast<unsigned long int>(b),rnd_mode);
   2676 }
   2677 
   2678 inline const mpreal pow(const mpreal& a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2679 {
   2680     mpreal x(a);
   2681     mpfr_pow_si(x.mp,x.mp,b,rnd_mode);
   2682     return x;
   2683 }
   2684 
   2685 inline const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode)
   2686 {
   2687     return pow(a,static_cast<long int>(b),rnd_mode);
   2688 }
   2689 
   2690 inline const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode)
   2691 {
   2692     return pow(a,mpreal(b),rnd_mode);
   2693 }
   2694 
   2695 inline const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode)
   2696 {
   2697     return pow(a,mpreal(b),rnd_mode);
   2698 }
   2699 
   2700 inline const mpreal pow(const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd())
   2701 {
   2702     mpreal x(a);
   2703     mpfr_ui_pow(x.mp,a,b.mp,rnd_mode);
   2704     return x;
   2705 }
   2706 
   2707 inline const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode)
   2708 {
   2709     return pow(static_cast<unsigned long int>(a),b,rnd_mode);
   2710 }
   2711 
   2712 inline const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode)
   2713 {
   2714     if (a>=0)     return pow(static_cast<unsigned long int>(a),b,rnd_mode);
   2715     else          return pow(mpreal(a),b,rnd_mode);
   2716 }
   2717 
   2718 inline const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode)
   2719 {
   2720     if (a>=0)     return pow(static_cast<unsigned long int>(a),b,rnd_mode);
   2721     else          return pow(mpreal(a),b,rnd_mode);
   2722 }
   2723 
   2724 inline const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode)
   2725 {
   2726     return pow(mpreal(a),b,rnd_mode);
   2727 }
   2728 
   2729 inline const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode)
   2730 {
   2731     return pow(mpreal(a),b,rnd_mode);
   2732 }
   2733 
   2734 // pow unsigned long int
   2735 inline const mpreal pow(const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode)
   2736 {
   2737     mpreal x(a);
   2738     mpfr_ui_pow_ui(x.mp,a,b,rnd_mode);
   2739     return x;
   2740 }
   2741 
   2742 inline const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode)
   2743 {
   2744     return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2745 }
   2746 
   2747 inline const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode)
   2748 {
   2749     if(b>0)    return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2750     else       return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
   2751 }
   2752 
   2753 inline const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode)
   2754 {
   2755     if(b>0)    return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2756     else       return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
   2757 }
   2758 
   2759 inline const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode)
   2760 {
   2761     return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
   2762 }
   2763 
   2764 inline const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode)
   2765 {
   2766     return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
   2767 }
   2768 
   2769 // pow unsigned int
   2770 inline const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode)
   2771 {
   2772     return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
   2773 }
   2774 
   2775 inline const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode)
   2776 {
   2777     return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2778 }
   2779 
   2780 inline const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode)
   2781 {
   2782     if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2783     else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2784 }
   2785 
   2786 inline const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode)
   2787 {
   2788     if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2789     else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2790 }
   2791 
   2792 inline const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode)
   2793 {
   2794     return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2795 }
   2796 
   2797 inline const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode)
   2798 {
   2799     return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2800 }
   2801 
   2802 // pow long int
   2803 inline const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode)
   2804 {
   2805     if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
   2806     else     return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
   2807 }
   2808 
   2809 inline const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode)
   2810 {
   2811     if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode);  //mpfr_ui_pow_ui
   2812     else     return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
   2813 }
   2814 
   2815 inline const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode)
   2816 {
   2817     if (a>0)
   2818     {
   2819         if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2820         else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2821     }else{
   2822         return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
   2823     }
   2824 }
   2825 
   2826 inline const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode)
   2827 {
   2828     if (a>0)
   2829     {
   2830         if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2831         else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2832     }else{
   2833         return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
   2834     }
   2835 }
   2836 
   2837 inline const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode)
   2838 {
   2839     if (a>=0)   return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2840     else        return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
   2841 }
   2842 
   2843 inline const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode)
   2844 {
   2845     if (a>=0)   return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2846     else        return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
   2847 }
   2848 
   2849 // pow int
   2850 inline const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode)
   2851 {
   2852     if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
   2853     else     return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
   2854 }
   2855 
   2856 inline const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode)
   2857 {
   2858     if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode);  //mpfr_ui_pow_ui
   2859     else     return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
   2860 }
   2861 
   2862 inline const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode)
   2863 {
   2864     if (a>0)
   2865     {
   2866         if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2867         else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2868     }else{
   2869         return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
   2870     }
   2871 }
   2872 
   2873 inline const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode)
   2874 {
   2875     if (a>0)
   2876     {
   2877         if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
   2878         else    return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2879     }else{
   2880         return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
   2881     }
   2882 }
   2883 
   2884 inline const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode)
   2885 {
   2886     if (a>=0)   return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2887     else        return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
   2888 }
   2889 
   2890 inline const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode)
   2891 {
   2892     if (a>=0)   return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
   2893     else        return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
   2894 }
   2895 
   2896 // pow long double
   2897 inline const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode)
   2898 {
   2899     return pow(mpreal(a),mpreal(b),rnd_mode);
   2900 }
   2901 
   2902 inline const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode)
   2903 {
   2904     return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
   2905 }
   2906 
   2907 inline const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode)
   2908 {
   2909     return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
   2910 }
   2911 
   2912 inline const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode)
   2913 {
   2914     return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
   2915 }
   2916 
   2917 inline const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode)
   2918 {
   2919     return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
   2920 }
   2921 
   2922 inline const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode)
   2923 {
   2924     return pow(mpreal(a),mpreal(b),rnd_mode);
   2925 }
   2926 
   2927 inline const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode)
   2928 {
   2929     return pow(mpreal(a),b,rnd_mode); // mpfr_pow_ui
   2930 }
   2931 
   2932 inline const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode)
   2933 {
   2934     return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); // mpfr_pow_ui
   2935 }
   2936 
   2937 inline const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode)
   2938 {
   2939     return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
   2940 }
   2941 
   2942 inline const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode)
   2943 {
   2944     return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
   2945 }
   2946 } // End of mpfr namespace
   2947 
   2948 // Explicit specialization of std::swap for mpreal numbers
   2949 // Thus standard algorithms will use efficient version of swap (due to Koenig lookup)
   2950 // Non-throwing swap C++ idiom: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-throwing_swap
   2951 namespace std
   2952 {
   2953   // we are allowed to extend namespace std with specializations only
   2954     template <>
   2955     inline void swap(mpfr::mpreal& x, mpfr::mpreal& y)
   2956     {
   2957         return mpfr::swap(x, y);
   2958     }
   2959 
   2960     template<>
   2961     class numeric_limits<mpfr::mpreal>
   2962     {
   2963     public:
   2964         static const bool is_specialized    = true;
   2965         static const bool is_signed         = true;
   2966         static const bool is_integer        = false;
   2967         static const bool is_exact          = false;
   2968         static const int  radix             = 2;
   2969 
   2970         static const bool has_infinity      = true;
   2971         static const bool has_quiet_NaN     = true;
   2972         static const bool has_signaling_NaN = true;
   2973 
   2974         static const bool is_iec559         = true;        // = IEEE 754
   2975         static const bool is_bounded        = true;
   2976         static const bool is_modulo         = false;
   2977         static const bool traps             = true;
   2978         static const bool tinyness_before   = true;
   2979 
   2980         static const float_denorm_style has_denorm  = denorm_absent;
   2981 
   2982         inline static mpfr::mpreal (min)    (mp_prec_t precision = mpfr::mpreal::get_default_prec()) {  return  mpfr::minval(precision);  }
   2983         inline static mpfr::mpreal (max)    (mp_prec_t precision = mpfr::mpreal::get_default_prec()) {  return  mpfr::maxval(precision);  }
   2984         inline static mpfr::mpreal lowest   (mp_prec_t precision = mpfr::mpreal::get_default_prec()) {  return -mpfr::maxval(precision);  }
   2985 
   2986         // Returns smallest eps such that 1 + eps != 1 (classic machine epsilon)
   2987         inline static mpfr::mpreal epsilon(mp_prec_t precision = mpfr::mpreal::get_default_prec()) {  return  mpfr::machine_epsilon(precision); }
   2988 
   2989         // Returns smallest eps such that x + eps != x (relative machine epsilon)
   2990         inline static mpfr::mpreal epsilon(const mpfr::mpreal& x) {  return mpfr::machine_epsilon(x);  }
   2991 
   2992         inline static mpfr::mpreal round_error(mp_prec_t precision = mpfr::mpreal::get_default_prec())
   2993         {
   2994             mp_rnd_t r = mpfr::mpreal::get_default_rnd();
   2995 
   2996             if(r == GMP_RNDN)  return mpfr::mpreal(0.5, precision);
   2997             else               return mpfr::mpreal(1.0, precision);
   2998         }
   2999 
   3000         inline static const mpfr::mpreal infinity()         { return mpfr::const_infinity();     }
   3001         inline static const mpfr::mpreal quiet_NaN()        { return mpfr::mpreal().setNan();    }
   3002         inline static const mpfr::mpreal signaling_NaN()    { return mpfr::mpreal().setNan();    }
   3003         inline static const mpfr::mpreal denorm_min()       { return (min)();                    }
   3004 
   3005         // Please note, exponent range is not fixed in MPFR
   3006         static const int min_exponent = MPFR_EMIN_DEFAULT;
   3007         static const int max_exponent = MPFR_EMAX_DEFAULT;
   3008         MPREAL_PERMISSIVE_EXPR static const int min_exponent10 = (int) (MPFR_EMIN_DEFAULT * 0.3010299956639811);
   3009         MPREAL_PERMISSIVE_EXPR static const int max_exponent10 = (int) (MPFR_EMAX_DEFAULT * 0.3010299956639811);
   3010 
   3011 #ifdef MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS
   3012 
   3013         // Following members should be constant according to standard, but they can be variable in MPFR
   3014         // So we define them as functions here.
   3015         //
   3016         // This is preferable way for std::numeric_limits<mpfr::mpreal> specialization.
   3017         // But it is incompatible with standard std::numeric_limits and might not work with other libraries, e.g. boost.
   3018         // See below for compatible implementation.
   3019         inline static float_round_style round_style()
   3020         {
   3021             mp_rnd_t r = mpfr::mpreal::get_default_rnd();
   3022 
   3023             switch (r)
   3024             {
   3025             case GMP_RNDN: return round_to_nearest;
   3026             case GMP_RNDZ: return round_toward_zero;
   3027             case GMP_RNDU: return round_toward_infinity;
   3028             case GMP_RNDD: return round_toward_neg_infinity;
   3029             default: return round_indeterminate;
   3030             }
   3031         }
   3032 
   3033         inline static int digits()                        {    return int(mpfr::mpreal::get_default_prec());    }
   3034         inline static int digits(const mpfr::mpreal& x)   {    return x.getPrecision();                         }
   3035 
   3036         inline static int digits10(mp_prec_t precision = mpfr::mpreal::get_default_prec())
   3037         {
   3038             return mpfr::bits2digits(precision);
   3039         }
   3040 
   3041         inline static int digits10(const mpfr::mpreal& x)
   3042         {
   3043             return mpfr::bits2digits(x.getPrecision());
   3044         }
   3045 
   3046         inline static int max_digits10(mp_prec_t precision = mpfr::mpreal::get_default_prec())
   3047         {
   3048             return digits10(precision);
   3049         }
   3050 #else
   3051         // Digits and round_style are NOT constants when it comes to mpreal.
   3052         // If possible, please use functions digits() and round_style() defined above.
   3053         //
   3054         // These (default) values are preserved for compatibility with existing libraries, e.g. boost.
   3055         // Change them accordingly to your application.
   3056         //
   3057         // For example, if you use 256 bits of precision uniformly in your program, then:
   3058         // digits       = 256
   3059         // digits10     = 77
   3060         // max_digits10 = 78
   3061         //
   3062         // Approximate formula for decimal digits is: digits10 = floor(log10(2) * digits). See bits2digits() for more details.
   3063 
   3064         static const std::float_round_style round_style = round_to_nearest;
   3065         static const int digits       = 53;
   3066         static const int digits10     = 15;
   3067         static const int max_digits10 = 16;
   3068 #endif
   3069     };
   3070 
   3071 }
   3072 
   3073 #endif /* __MPREAL_H__ */
   3074