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