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