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