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