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@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
128namespace mpfr {
129
130class mpreal {
131private:
132	mpfr_t mp;
133
134public:
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
140public:
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
521private:
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
532private:
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
546class conversion_overflow : public std::exception {
547public:
548	std::string why() { return "inexact conversion from floating point"; }
549};
550
551namespace 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
574template <typename Rhs>
575inline const typename internal::result_type<Rhs>::type
576	operator+(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) += rhs;	}
577
578template <typename Lhs>
579inline const typename internal::result_type<Lhs>::type
580	operator+(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) += lhs;	}
581
582// - Subtraction
583template <typename Rhs>
584inline const typename internal::result_type<Rhs>::type
585	operator-(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) -= rhs;	}
586
587template <typename Lhs>
588inline const typename internal::result_type<Lhs>::type
589	operator-(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) -= rhs;	}
590
591// * Multiplication
592template <typename Rhs>
593inline const typename internal::result_type<Rhs>::type
594	operator*(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) *= rhs;	}
595
596template <typename Lhs>
597inline const typename internal::result_type<Lhs>::type
598	operator*(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) *= lhs;	}
599
600// / Division
601template <typename Rhs>
602inline const typename internal::result_type<Rhs>::type
603	operator/(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) /= rhs;	}
604
605template <typename Lhs>
606inline const typename internal::result_type<Lhs>::type
607	operator/(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) /= rhs;	}
608
609//////////////////////////////////////////////////////////////////////////
610// sqrt
611const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
612const mpreal sqrt(const long int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
613const mpreal sqrt(const int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
614const mpreal sqrt(const long double v, mp_rnd_t rnd_mode = mpreal::default_rnd);
615const mpreal sqrt(const double v, mp_rnd_t rnd_mode = mpreal::default_rnd);
616
617//////////////////////////////////////////////////////////////////////////
618// pow
619const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
620const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
621const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
622const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
623
624const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
625const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
626const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
627const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
628const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
629
630const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
631const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
632const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
633const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
634const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
635
636const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
637const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
638const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
639const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
640const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
641const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
642
643const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
644const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
645const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
646const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
647const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
648const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
649
650const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
651const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
652const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
653const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
654const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
655const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
656
657const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
658const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
659const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
660const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
661const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
662
663const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
664const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
665const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
666const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
667const 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
672inline 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
675inline const mpreal machine_epsilon(const mpreal& x);
676
677inline const mpreal mpreal_min(mp_prec_t prec = mpreal::get_default_prec());
678inline const mpreal mpreal_max(mp_prec_t prec = mpreal::get_default_prec());
679inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps);
680inline 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
687inline mp_prec_t digits2bits(int d);
688inline int bits2digits(mp_prec_t b);
689
690//////////////////////////////////////////////////////////////////////////
691// min, max
692const mpreal (max)(const mpreal& x, const mpreal& y);
693const mpreal (min)(const mpreal& x, const mpreal& y);
694
695//////////////////////////////////////////////////////////////////////////
696// Implementation
697//////////////////////////////////////////////////////////////////////////
698
699//////////////////////////////////////////////////////////////////////////
700// Operators - Assignment
701inline 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
714inline 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
722inline 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
730inline 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
738inline 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
746inline 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
760inline 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
768inline 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
776inline 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
784inline 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
794inline 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
801inline mpreal& mpreal::operator+=(const mpf_t u)
802{
803	*this += mpreal(u);
804	MPREAL_MSVC_DEBUGVIEW_CODE;
805	return *this;
806}
807
808inline 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
815inline 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
822inline mpreal& mpreal::operator+= (const long double u)
823{
824	*this += mpreal(u);
825	MPREAL_MSVC_DEBUGVIEW_CODE;
826	return *this;
827}
828
829inline 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
841inline 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
848inline 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
855inline 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
862inline 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)
870inline mpreal& mpreal::operator+=(const int64_t  u){	*this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;	}
871inline mpreal& mpreal::operator+=(const uint64_t u){	*this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;	}
872inline mpreal& mpreal::operator-=(const int64_t  u){	*this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;	}
873inline mpreal& mpreal::operator-=(const uint64_t u){	*this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;	}
874inline mpreal& mpreal::operator*=(const int64_t  u){	*this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;	}
875inline mpreal& mpreal::operator*=(const uint64_t u){	*this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;	}
876inline mpreal& mpreal::operator/=(const int64_t  u){	*this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;	}
877inline mpreal& mpreal::operator/=(const uint64_t u){	*this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this;	}
878#endif
879
880inline const mpreal mpreal::operator+()const	{	return mpreal(*this); }
881
882inline 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
889inline mpreal& mpreal::operator++()
890{
891	return *this += 1;
892}
893
894inline const mpreal mpreal::operator++ (int)
895{
896	mpreal x(*this);
897	*this += 1;
898	return x;
899}
900
901inline mpreal& mpreal::operator--()
902{
903	return *this -= 1;
904}
905
906inline const mpreal mpreal::operator-- (int)
907{
908	mpreal x(*this);
909	*this -= 1;
910	return x;
911}
912
913//////////////////////////////////////////////////////////////////////////
914// - Subtraction
915inline 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
922inline 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
929inline 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
936inline mpreal& mpreal::operator-=(const long double v)
937{
938	*this -= mpreal(v);
939	MPREAL_MSVC_DEBUGVIEW_CODE;
940	return *this;
941}
942
943inline 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
955inline 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
962inline 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
969inline 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
976inline 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
983inline const mpreal mpreal::operator-()const
984{
985	mpreal u(*this);
986	mpfr_neg(u.mp,u.mp,default_rnd);
987	return u;
988}
989
990inline 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
1003inline 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
1014inline 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
1021inline 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
1028inline 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
1035inline 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
1044inline 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
1051inline 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
1058inline 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
1065inline mpreal& mpreal::operator*=(const long double v)
1066{
1067	*this *= mpreal(v);
1068	MPREAL_MSVC_DEBUGVIEW_CODE;
1069	return *this;
1070}
1071
1072inline 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
1084inline 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
1091inline 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
1098inline 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
1105inline 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
1112inline 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
1121inline 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
1128inline 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
1135inline 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
1142inline mpreal& mpreal::operator/=(const long double v)
1143{
1144	*this /= mpreal(v);
1145	MPREAL_MSVC_DEBUGVIEW_CODE;
1146	return *this;
1147}
1148
1149inline 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
1160inline 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
1167inline 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
1174inline 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
1181inline 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
1188inline 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
1202inline 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
1209inline 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
1216inline 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
1223inline 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
1230inline 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
1243inline 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
1250inline 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
1257inline 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
1264inline 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
1271inline 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
1278inline 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
1285inline 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
1292inline 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
1299inline const mpreal operator<<(const mpreal& v, const unsigned long int k)
1300{
1301	return mul_2ui(v,k);
1302}
1303
1304inline const mpreal operator<<(const mpreal& v, const unsigned int k)
1305{
1306	return mul_2ui(v,static_cast<unsigned long int>(k));
1307}
1308
1309inline const mpreal operator<<(const mpreal& v, const long int k)
1310{
1311	return mul_2si(v,k);
1312}
1313
1314inline const mpreal operator<<(const mpreal& v, const int k)
1315{
1316	return mul_2si(v,static_cast<long int>(k));
1317}
1318
1319inline const mpreal operator>>(const mpreal& v, const unsigned long int k)
1320{
1321	return div_2ui(v,k);
1322}
1323
1324inline const mpreal operator>>(const mpreal& v, const long int k)
1325{
1326	return div_2si(v,k);
1327}
1328
1329inline const mpreal operator>>(const mpreal& v, const unsigned int k)
1330{
1331	return div_2ui(v,static_cast<unsigned long int>(k));
1332}
1333
1334inline 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
1340inline 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
1348inline 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
1355inline 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
1362inline 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
1371inline bool operator >	(const mpreal& a, const mpreal& b){	return (mpfr_greater_p(a.mp,b.mp)		!=0);	}
1372inline bool operator >= (const mpreal& a, const mpreal& b){	return (mpfr_greaterequal_p(a.mp,b.mp)	!=0);	}
1373inline bool operator <  (const mpreal& a, const mpreal& b){	return (mpfr_less_p(a.mp,b.mp)			!=0);	}
1374inline bool operator <= (const mpreal& a, const mpreal& b){	return (mpfr_lessequal_p(a.mp,b.mp)		!=0);	}
1375inline bool operator == (const mpreal& a, const mpreal& b){	return (mpfr_equal_p(a.mp,b.mp)			!=0);	}
1376inline bool operator != (const mpreal& a, const mpreal& b){	return (mpfr_lessgreater_p(a.mp,b.mp)	!=0);	}
1377
1378inline bool operator == (const mpreal& a, const unsigned long int b	){	return (mpfr_cmp_ui(a.mp,b) == 0);	}
1379inline bool operator == (const mpreal& a, const unsigned int b		){	return (mpfr_cmp_ui(a.mp,b) == 0);	}
1380inline bool operator == (const mpreal& a, const long int b			){	return (mpfr_cmp_si(a.mp,b) == 0);	}
1381inline bool operator == (const mpreal& a, const int b				){	return (mpfr_cmp_si(a.mp,b) == 0);	}
1382inline bool operator == (const mpreal& a, const long double b		){	return (mpfr_cmp_ld(a.mp,b) == 0);	}
1383inline bool operator == (const mpreal& a, const double b			){	return (mpfr_cmp_d(a.mp,b)  == 0);	}
1384
1385
1386inline bool isnan	(const mpreal& v){	return (mpfr_nan_p(v.mp)		!= 0);	}
1387inline bool isinf	(const mpreal& v){	return (mpfr_inf_p(v.mp)		!= 0);	}
1388inline bool isfinite(const mpreal& v){	return (mpfr_number_p(v.mp)		!= 0);	}
1389inline bool iszero	(const mpreal& v){	return (mpfr_zero_p(v.mp)		!= 0);	}
1390inline bool isint	(const mpreal& v){	return (mpfr_integer_p(v.mp)	!= 0);	}
1391
1392#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
1393inline bool isregular(const mpreal& v){	return (mpfr_regular_p(v.mp));}
1394#endif
1395
1396//////////////////////////////////////////////////////////////////////////
1397// Type Converters
1398inline long				mpreal::toLong()	const	{	return mpfr_get_si(mp,GMP_RNDZ);	}
1399inline unsigned long	mpreal::toULong()	const	{	return mpfr_get_ui(mp,GMP_RNDZ);	}
1400inline double			mpreal::toDouble()	const	{	return mpfr_get_d(mp,default_rnd);	}
1401inline long double		mpreal::toLDouble()	const	{	return mpfr_get_ld(mp,default_rnd);	}
1402
1403#if defined (MPREAL_HAVE_INT64_SUPPORT)
1404inline int64_t	 mpreal::toInt64()	const{	return mpfr_get_sj(mp,GMP_RNDZ);	}
1405inline uint64_t	 mpreal::toUInt64()	const{	return mpfr_get_uj(mp,GMP_RNDZ);	}
1406#endif
1407
1408inline ::mpfr_ptr		mpreal::mpfr_ptr()			{	return mp;	}
1409inline ::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
1416inline 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
1425inline 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
1436inline int sgn(const mpreal& v)
1437{
1438	int r = mpfr_signbit(v.mp);
1439	return (r>0?-1:1);
1440}
1441
1442inline 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
1449inline int mpreal::getPrecision() const
1450{
1451	return mpfr_get_prec(mp);
1452}
1453
1454inline 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
1461inline mpreal& mpreal::setInf(int sign)
1462{
1463	mpfr_set_inf(mp,sign);
1464	MPREAL_MSVC_DEBUGVIEW_CODE;
1465	return *this;
1466}
1467
1468inline mpreal& mpreal::setNan()
1469{
1470	mpfr_set_nan(mp);
1471	MPREAL_MSVC_DEBUGVIEW_CODE;
1472	return *this;
1473}
1474
1475inline mpreal&	mpreal::setZero(int sign)
1476{
1477	mpfr_set_zero(mp,sign);
1478	MPREAL_MSVC_DEBUGVIEW_CODE;
1479	return *this;
1480}
1481
1482inline mp_prec_t mpreal::get_prec() const
1483{
1484	return mpfr_get_prec(mp);
1485}
1486
1487inline 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
1493inline mp_exp_t mpreal::get_exp ()
1494{
1495	return mpfr_get_exp(mp);
1496}
1497
1498inline 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
1505inline 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
1513inline 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
1522inline 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
1529inline 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
1539inline 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
1546inline 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
1555inline 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
1563inline 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
1568inline bool isEqualFuzzy(const mpreal& a, const mpreal& b)
1569{
1570	return isEqualFuzzy(a,b,machine_epsilon((std::min)(abs(a), abs(b))));
1571}
1572
1573inline 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
1583inline int mpreal::check_range (int t, mp_rnd_t rnd_mode)
1584{
1585	return mpfr_check_range(mp,t,rnd_mode);
1586}
1587
1588inline 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
1595inline mp_exp_t mpreal::get_emin (void)
1596{
1597	return mpfr_get_emin();
1598}
1599
1600inline int mpreal::set_emin (mp_exp_t exp)
1601{
1602	return mpfr_set_emin(exp);
1603}
1604
1605inline mp_exp_t mpreal::get_emax (void)
1606{
1607	return mpfr_get_emax();
1608}
1609
1610inline int mpreal::set_emax (mp_exp_t exp)
1611{
1612	return mpfr_set_emax(exp);
1613}
1614
1615inline mp_exp_t mpreal::get_emin_min (void)
1616{
1617	return mpfr_get_emin_min();
1618}
1619
1620inline mp_exp_t mpreal::get_emin_max (void)
1621{
1622	return mpfr_get_emin_max();
1623}
1624
1625inline mp_exp_t mpreal::get_emax_min (void)
1626{
1627	return mpfr_get_emax_min();
1628}
1629
1630inline mp_exp_t mpreal::get_emax_max (void)
1631{
1632	return mpfr_get_emax_max();
1633}
1634
1635//////////////////////////////////////////////////////////////////////////
1636// Mathematical Functions
1637//////////////////////////////////////////////////////////////////////////
1638inline 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
1645inline 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
1652inline 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
1659inline 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
1664inline 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
1670inline 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
1676inline const mpreal sqrt(const long double v, mp_rnd_t rnd_mode)
1677{
1678	return sqrt(mpreal(v),rnd_mode);
1679}
1680
1681inline const mpreal sqrt(const double v, mp_rnd_t rnd_mode)
1682{
1683	return sqrt(mpreal(v),rnd_mode);
1684}
1685
1686inline 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
1693inline 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
1700inline 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
1707inline 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
1714inline 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
1721inline int cmpabs(const mpreal& a,const mpreal& b)
1722{
1723	return mpfr_cmpabs(a.mp,b.mp);
1724}
1725
1726inline 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
1733inline 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
1740inline 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
1747inline 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
1754inline 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
1761inline 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
1768inline 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
1775inline 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
1782inline 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
1789inline 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
1796inline 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
1803inline 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
1810inline 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
1815inline 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
1822inline 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
1829inline 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
1836inline const mpreal acot (const mpreal& v, mp_rnd_t rnd_mode)
1837{
1838	return atan(1/v, rnd_mode);
1839}
1840
1841inline const mpreal asec (const mpreal& v, mp_rnd_t rnd_mode)
1842{
1843	return acos(1/v, rnd_mode);
1844}
1845
1846inline const mpreal acsc (const mpreal& v, mp_rnd_t rnd_mode)
1847{
1848	return asin(1/v, rnd_mode);
1849}
1850
1851inline const mpreal acoth (const mpreal& v, mp_rnd_t rnd_mode)
1852{
1853	return atanh(1/v, rnd_mode);
1854}
1855
1856inline const mpreal asech (const mpreal& v, mp_rnd_t rnd_mode)
1857{
1858	return acosh(1/v, rnd_mode);
1859}
1860
1861inline const mpreal acsch (const mpreal& v, mp_rnd_t rnd_mode)
1862{
1863	return asinh(1/v, rnd_mode);
1864}
1865
1866inline 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
1881inline 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
1888inline 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
1895inline 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
1902inline 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
1909inline 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
1916inline 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
1923inline 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
1930inline 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
1937inline 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
1944inline 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
1959inline 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
1974inline 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
1981inline 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
1988inline 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
1995inline 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
2002inline 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
2013inline 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
2020inline 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
2033inline 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
2040inline 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
2047inline 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
2054inline 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
2061inline 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
2068inline 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
2075inline 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
2082inline 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
2089inline 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
2100inline 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
2105inline 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
2112inline 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
2127inline 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
2139inline 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
2146inline 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
2157inline 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
2165inline 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
2173inline 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
2181inline 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
2189inline 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
2199inline 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
2206inline const mpreal ceil(const mpreal& v)
2207{
2208	mpreal x(v);
2209	mpfr_ceil(x.mp,v.mp);
2210	return x;
2211
2212}
2213
2214inline const mpreal floor(const mpreal& v)
2215{
2216	mpreal x(v);
2217	mpfr_floor(x.mp,v.mp);
2218	return x;
2219}
2220
2221inline const mpreal round(const mpreal& v)
2222{
2223	mpreal x(v);
2224	mpfr_round(x.mp,v.mp);
2225	return x;
2226}
2227
2228inline const mpreal trunc(const mpreal& v)
2229{
2230	mpreal x(v);
2231	mpfr_trunc(x.mp,v.mp);
2232	return x;
2233}
2234
2235inline 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
2242inline 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
2249inline 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
2256inline 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
2263inline 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
2272inline void swap(mpreal& a, mpreal& b)
2273{
2274	mpfr_swap(a.mp,b.mp);
2275}
2276
2277inline const mpreal (max)(const mpreal& x, const mpreal& y)
2278{
2279	return (x>y?x:y);
2280}
2281
2282inline const mpreal (min)(const mpreal& x, const mpreal& y)
2283{
2284	return (x<y?x:y);
2285}
2286
2287inline 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
2294inline 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
2301inline 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
2308inline const mpreal nextabove  (const mpreal& x)
2309{
2310	mpreal a(x);
2311	mpfr_nextabove(a.mp);
2312	return a;
2313}
2314
2315inline const mpreal nextbelow  (const mpreal& x)
2316{
2317	mpreal a(x);
2318	mpfr_nextbelow(a.mp);
2319	return a;
2320}
2321
2322inline 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
2331inline 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))
2340inline 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
2352inline 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
2378inline void mpreal::set_default_prec(mp_prec_t prec)
2379{
2380	default_prec = prec;
2381	mpfr_set_default_prec(prec);
2382}
2383
2384inline mp_prec_t mpreal::get_default_prec()
2385{
2386	return (mpfr_get_default_prec)();
2387}
2388
2389inline void mpreal::set_default_base(int base)
2390{
2391	default_base = base;
2392}
2393
2394inline int mpreal::get_default_base()
2395{
2396	return default_base;
2397}
2398
2399inline 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
2405inline mp_rnd_t mpreal::get_default_rnd()
2406{
2407	return static_cast<mp_rnd_t>((mpfr_get_default_rounding_mode)());
2408}
2409
2410inline void mpreal::set_double_bits(int dbits)
2411{
2412	double_bits = dbits;
2413}
2414
2415inline int mpreal::get_double_bits()
2416{
2417	return double_bits;
2418}
2419
2420inline 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
2427inline 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
2434inline 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
2441inline 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
2448inline 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
2453inline 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
2460inline 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
2465inline 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
2470inline 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
2475inline 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
2482inline 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
2487inline 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
2493inline 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
2499inline 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
2504inline 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
2510inline 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
2517inline 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
2522inline 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
2528inline 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
2534inline 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
2539inline 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
2545inline 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
2550inline 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
2555inline 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
2561inline 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
2567inline 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
2572inline 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
2578inline 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
2584inline 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
2590inline 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
2601inline 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
2612inline 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
2618inline 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
2625inline 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
2631inline 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
2637inline 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
2648inline 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
2659inline 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
2665inline 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
2672inline 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
2677inline 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
2682inline 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
2687inline 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
2692inline 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
2697inline 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
2702inline 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
2707inline 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
2712inline 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
2717inline 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
2726namespace 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