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