You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							597 lines
						
					
					
						
							13 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							597 lines
						
					
					
						
							13 KiB
						
					
					
				
								/*
							 | 
						|
									Multi-precision real number class. C++ interface fo MPFR library.
							 | 
						|
									Project homepage: http://www.holoborodko.com/pavel/
							 | 
						|
									Contact e-mail:   pavel@holoborodko.com
							 | 
						|
								
							 | 
						|
									Copyright (c) 2008-2011 Pavel Holoborodko
							 | 
						|
								
							 | 
						|
									Core Developers: 
							 | 
						|
									Pavel Holoborodko, Dmitriy Gubanov, Konstantin Holoborodko. 
							 | 
						|
								
							 | 
						|
									Contributors:
							 | 
						|
									Brian Gladman, Helmut Jarausch, Fokko Beekhof, Ulrich Mutze, 
							 | 
						|
									Heinz van Saanen, Pere Constans, Peter van Hoof, Gael Guennebaud, 
							 | 
						|
									Tsai Chia Cheng, Alexei Zubanov.
							 | 
						|
								
							 | 
						|
									****************************************************************************
							 | 
						|
									This library is free software; you can redistribute it and/or
							 | 
						|
									modify it under the terms of the GNU Lesser General Public
							 | 
						|
									License as published by the Free Software Foundation; either
							 | 
						|
									version 2.1 of the License, or (at your option) any later version.
							 | 
						|
								
							 | 
						|
									This library is distributed in the hope that it will be useful,
							 | 
						|
									but WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						|
									MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
							 | 
						|
									Lesser General Public License for more details.
							 | 
						|
								
							 | 
						|
									You should have received a copy of the GNU Lesser General Public
							 | 
						|
									License along with this library; if not, write to the Free Software
							 | 
						|
									Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
							 | 
						|
								
							 | 
						|
									****************************************************************************
							 | 
						|
									****************************************************************************
							 | 
						|
									Redistribution and use in source and binary forms, with or without
							 | 
						|
									modification, are permitted provided that the following conditions
							 | 
						|
									are met:
							 | 
						|
								
							 | 
						|
									1. Redistributions of source code must retain the above copyright
							 | 
						|
									notice, this list of conditions and the following disclaimer.
							 | 
						|
								
							 | 
						|
									2. Redistributions in binary form must reproduce the above copyright
							 | 
						|
									notice, this list of conditions and the following disclaimer in the
							 | 
						|
									documentation and/or other materials provided with the distribution.
							 | 
						|
								
							 | 
						|
									3. The name of the author may be used to endorse or promote products
							 | 
						|
									derived from this software without specific prior written permission.
							 | 
						|
								
							 | 
						|
									THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
							 | 
						|
									ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
							 | 
						|
									IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
							 | 
						|
									ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
							 | 
						|
									FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
							 | 
						|
									DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
							 | 
						|
									OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
							 | 
						|
									HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
							 | 
						|
									LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
							 | 
						|
									OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
							 | 
						|
									SUCH DAMAGE.
							 | 
						|
								*/
							 | 
						|
								#include <cstring>
							 | 
						|
								#include "mpreal.h"
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
								#include "dlmalloc.h"
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								using std::ws;
							 | 
						|
								using std::cerr;
							 | 
						|
								using std::endl;
							 | 
						|
								using std::string;
							 | 
						|
								using std::ostream;
							 | 
						|
								using std::istream;
							 | 
						|
								
							 | 
						|
								namespace mpfr{
							 | 
						|
								
							 | 
						|
								mp_rnd_t   mpreal::default_rnd  = MPFR_RNDN;	//(mpfr_get_default_rounding_mode)();	
							 | 
						|
								mp_prec_t  mpreal::default_prec = 64;			//(mpfr_get_default_prec)();	
							 | 
						|
								int		   mpreal::default_base = 10;
							 | 
						|
								int        mpreal::double_bits = -1;
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
								bool       mpreal::is_custom_malloc = false;
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								// Default constructor: creates mp number and initializes it to 0.
							 | 
						|
								mpreal::mpreal() 
							 | 
						|
								{ 
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,default_prec); 
							 | 
						|
									mpfr_set_ui(mp,0,default_rnd);
							 | 
						|
								
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const mpreal& u) 
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,mpfr_get_prec(u.mp));
							 | 
						|
									mpfr_set(mp,u.mp,default_rnd);
							 | 
						|
								
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const mpfr_t u)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,mpfr_get_prec(u));
							 | 
						|
									mpfr_set(mp,u,default_rnd);
							 | 
						|
									
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const mpf_t u)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,(mp_prec_t) mpf_get_prec(u)); // (gmp: mp_bitcnt_t) unsigned long -> long (mpfr: mp_prec_t)
							 | 
						|
									mpfr_set_f(mp,u,default_rnd);
							 | 
						|
								
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const mpz_t u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_z(mp,u,mode);
							 | 
						|
									
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const mpq_t u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_q(mp,u,mode);
							 | 
						|
									
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								    if(double_bits == -1 || fits_in_bits(u, double_bits))
							 | 
						|
								    {
							 | 
						|
								    	mpfr_init2(mp,prec);
							 | 
						|
									    mpfr_set_d(mp,u,mode);
							 | 
						|
										
							 | 
						|
										MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								    }
							 | 
						|
								    else
							 | 
						|
								        throw conversion_overflow();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const long double u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{ 
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								    mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_ld(mp,u,mode);
							 | 
						|
									
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const unsigned long int u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{ 
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_ui(mp,u,mode);
							 | 
						|
									
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const unsigned int u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{ 
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_ui(mp,u,mode);
							 | 
						|
								
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const long int u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{ 
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_si(mp,u,mode);
							 | 
						|
								
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{ 
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_si(mp,u,mode);
							 | 
						|
								
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_INT64_SUPPORT)
							 | 
						|
								mpreal::mpreal(const uint64_t u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_uj(mp, u, mode); 
							 | 
						|
								
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const int64_t u, mp_prec_t prec, mp_rnd_t mode)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_sj(mp, u, mode); 
							 | 
						|
									
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_str(mp, s, base, mode); 
							 | 
						|
								
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::mpreal(const std::string& s, mp_prec_t prec, int base, mp_rnd_t mode)
							 | 
						|
								{
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									mpfr_init2(mp,prec);
							 | 
						|
									mpfr_set_str(mp, s.c_str(), base, mode); 
							 | 
						|
								
							 | 
						|
									MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								mpreal::~mpreal() 
							 | 
						|
								{ 
							 | 
						|
									mpfr_clear(mp);
							 | 
						|
								}                           
							 | 
						|
								
							 | 
						|
								// Operators - Assignment
							 | 
						|
								mpreal& mpreal::operator=(const char* s)
							 | 
						|
								{
							 | 
						|
									mpfr_t t;
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									if(0==mpfr_init_set_str(t,s,default_base,default_rnd))
							 | 
						|
									{
							 | 
						|
										// We will rewrite mp anyway, so flash it and resize
							 | 
						|
										mpfr_set_prec(mp,mpfr_get_prec(t)); 
							 | 
						|
										mpfr_set(mp,t,mpreal::default_rnd);
							 | 
						|
										mpfr_clear(t);
							 | 
						|
								
							 | 
						|
										MPREAL_MSVC_DEBUGVIEW_CODE;
							 | 
						|
								
							 | 
						|
									}else{
							 | 
						|
										mpfr_clear(t);
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									return *this;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode)
							 | 
						|
								{
							 | 
						|
									mpreal a;
							 | 
						|
									mp_prec_t p1, p2, p3;
							 | 
						|
								
							 | 
						|
									p1 = v1.get_prec(); 
							 | 
						|
									p2 = v2.get_prec(); 
							 | 
						|
									p3 = v3.get_prec(); 
							 | 
						|
								
							 | 
						|
									a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
							 | 
						|
								
							 | 
						|
									mpfr_fma(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
							 | 
						|
									return a;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode)
							 | 
						|
								{
							 | 
						|
									mpreal a;
							 | 
						|
									mp_prec_t p1, p2, p3;
							 | 
						|
								
							 | 
						|
									p1 = v1.get_prec(); 
							 | 
						|
									p2 = v2.get_prec(); 
							 | 
						|
									p3 = v3.get_prec(); 
							 | 
						|
								
							 | 
						|
									a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
							 | 
						|
								
							 | 
						|
									mpfr_fms(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
							 | 
						|
									return a;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode)
							 | 
						|
								{
							 | 
						|
									mpreal a;
							 | 
						|
									mp_prec_t p1, p2;
							 | 
						|
								
							 | 
						|
									p1 = v1.get_prec(); 
							 | 
						|
									p2 = v2.get_prec(); 
							 | 
						|
								
							 | 
						|
									a.set_prec(p1>p2?p1:p2);
							 | 
						|
								
							 | 
						|
									mpfr_agm(a.mp, v1.mp, v2.mp, rnd_mode);
							 | 
						|
								
							 | 
						|
									return a;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode)
							 | 
						|
								{
							 | 
						|
									mpreal x;
							 | 
						|
									mpfr_ptr* t;
							 | 
						|
									unsigned long int i;
							 | 
						|
								
							 | 
						|
									t = new mpfr_ptr[n];
							 | 
						|
									for (i=0;i<n;i++) t[i] = (mpfr_ptr)tab[i].mp;
							 | 
						|
									mpfr_sum(x.mp,t,n,rnd_mode);
							 | 
						|
									delete[] t;
							 | 
						|
									return x;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
							 | 
						|
								{
							 | 
						|
									mpreal a;
							 | 
						|
									mp_prec_t yp, xp;
							 | 
						|
								
							 | 
						|
									yp = y.get_prec(); 
							 | 
						|
									xp = x.get_prec(); 
							 | 
						|
								
							 | 
						|
									a.set_prec(yp>xp?yp:xp);
							 | 
						|
								
							 | 
						|
									mpfr_remquo(a.mp,q, x.mp, y.mp, rnd_mode);
							 | 
						|
								
							 | 
						|
									return a;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								template <class T>
							 | 
						|
								std::string toString(T t, std::ios_base & (*f)(std::ios_base&))
							 | 
						|
								{
							 | 
						|
									std::ostringstream oss;
							 | 
						|
									oss << f << t;
							 | 
						|
									return oss.str();
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
							 | 
						|
								
							 | 
						|
								std::string mpreal::toString(const std::string& format) const
							 | 
						|
								{
							 | 
						|
									char *s = NULL;
							 | 
						|
									string out;
							 | 
						|
								
							 | 
						|
									if( !format.empty() )
							 | 
						|
									{
							 | 
						|
										if(!(mpfr_asprintf(&s,format.c_str(),mp) < 0))
							 | 
						|
										{
							 | 
						|
											out = std::string(s);
							 | 
						|
								
							 | 
						|
											mpfr_free_str(s);
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									return out;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								std::string mpreal::toString(int n, int b, mp_rnd_t mode) const
							 | 
						|
								{
							 | 
						|
								  (void)b;
							 | 
						|
								  (void)mode;
							 | 
						|
								#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
							 | 
						|
								
							 | 
						|
									// Use MPFR native function for output
							 | 
						|
									char format[128];
							 | 
						|
									int digits;
							 | 
						|
								
							 | 
						|
									digits = n > 0 ? n : bits2digits(mpfr_get_prec(mp));
							 | 
						|
								
							 | 
						|
									sprintf(format,"%%.%dRNg",digits);		// Default format
							 | 
						|
								
							 | 
						|
									return toString(std::string(format));
							 | 
						|
								
							 | 
						|
								#else
							 | 
						|
								
							 | 
						|
									char *s, *ns = NULL; 
							 | 
						|
									size_t slen, nslen;
							 | 
						|
									mp_exp_t exp;
							 | 
						|
									string out;
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									set_custom_malloc();
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
									if(mpfr_inf_p(mp))
							 | 
						|
									{ 
							 | 
						|
										if(mpfr_sgn(mp)>0) return "+Inf";
							 | 
						|
										else			   return "-Inf";
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									if(mpfr_zero_p(mp)) return "0";
							 | 
						|
									if(mpfr_nan_p(mp))  return "NaN";
							 | 
						|
								
							 | 
						|
									s  = mpfr_get_str(NULL,&exp,b,0,mp,mode);
							 | 
						|
									ns = mpfr_get_str(NULL,&exp,b,n,mp,mode);
							 | 
						|
								
							 | 
						|
									if(s!=NULL && ns!=NULL)
							 | 
						|
									{
							 | 
						|
										slen  = strlen(s);
							 | 
						|
										nslen = strlen(ns);
							 | 
						|
										if(nslen<=slen) 
							 | 
						|
										{
							 | 
						|
											mpfr_free_str(s);
							 | 
						|
											s = ns;
							 | 
						|
											slen = nslen;
							 | 
						|
										}
							 | 
						|
										else {
							 | 
						|
											mpfr_free_str(ns);
							 | 
						|
										}
							 | 
						|
								
							 | 
						|
										// Make human eye-friendly formatting if possible
							 | 
						|
										if (exp>0 && static_cast<size_t>(exp)<slen)
							 | 
						|
										{
							 | 
						|
											if(s[0]=='-')
							 | 
						|
											{
							 | 
						|
												// Remove zeros starting from right end
							 | 
						|
												char* ptr = s+slen-1;
							 | 
						|
												while (*ptr=='0' && ptr>s+exp) ptr--; 
							 | 
						|
								
							 | 
						|
												if(ptr==s+exp) out = string(s,exp+1);
							 | 
						|
												else		   out = string(s,exp+1)+'.'+string(s+exp+1,ptr-(s+exp+1)+1);
							 | 
						|
								
							 | 
						|
												//out = string(s,exp+1)+'.'+string(s+exp+1);
							 | 
						|
											}
							 | 
						|
											else
							 | 
						|
											{
							 | 
						|
												// Remove zeros starting from right end
							 | 
						|
												char* ptr = s+slen-1;
							 | 
						|
												while (*ptr=='0' && ptr>s+exp-1) ptr--; 
							 | 
						|
								
							 | 
						|
												if(ptr==s+exp-1) out = string(s,exp);
							 | 
						|
												else		     out = string(s,exp)+'.'+string(s+exp,ptr-(s+exp)+1);
							 | 
						|
								
							 | 
						|
												//out = string(s,exp)+'.'+string(s+exp);
							 | 
						|
											}
							 | 
						|
								
							 | 
						|
										}else{ // exp<0 || exp>slen
							 | 
						|
											if(s[0]=='-')
							 | 
						|
											{
							 | 
						|
												// Remove zeros starting from right end
							 | 
						|
												char* ptr = s+slen-1;
							 | 
						|
												while (*ptr=='0' && ptr>s+1) ptr--; 
							 | 
						|
								
							 | 
						|
												if(ptr==s+1) out = string(s,2);
							 | 
						|
												else		 out = string(s,2)+'.'+string(s+2,ptr-(s+2)+1);
							 | 
						|
								
							 | 
						|
												//out = string(s,2)+'.'+string(s+2);
							 | 
						|
											}
							 | 
						|
											else
							 | 
						|
											{
							 | 
						|
												// Remove zeros starting from right end
							 | 
						|
												char* ptr = s+slen-1;
							 | 
						|
												while (*ptr=='0' && ptr>s) ptr--; 
							 | 
						|
								
							 | 
						|
												if(ptr==s) out = string(s,1);
							 | 
						|
												else	   out = string(s,1)+'.'+string(s+1,ptr-(s+1)+1);
							 | 
						|
								
							 | 
						|
												//out = string(s,1)+'.'+string(s+1);
							 | 
						|
											}
							 | 
						|
								
							 | 
						|
											// Make final string
							 | 
						|
											if(--exp)
							 | 
						|
											{
							 | 
						|
												if(exp>0) out += "e+"+mpfr::toString<mp_exp_t>(exp,std::dec);
							 | 
						|
												else 	  out += "e"+mpfr::toString<mp_exp_t>(exp,std::dec);
							 | 
						|
											}
							 | 
						|
										}
							 | 
						|
								
							 | 
						|
										mpfr_free_str(s);
							 | 
						|
										return out;
							 | 
						|
									}else{
							 | 
						|
										return "conversion error!";
							 | 
						|
									}
							 | 
						|
								#endif
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								//////////////////////////////////////////////////////////////////////////
							 | 
						|
								// I/O
							 | 
						|
								ostream& operator<<(ostream& os, const mpreal& v)
							 | 
						|
								{
							 | 
						|
									return os<<v.toString(static_cast<int>(os.precision()));
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								istream& operator>>(istream &is, mpreal& v)
							 | 
						|
								{
							 | 
						|
									string tmp;
							 | 
						|
									is >> tmp;
							 | 
						|
									mpfr_set_str(v.mp, tmp.c_str(),mpreal::default_base,mpreal::default_rnd);
							 | 
						|
									return is;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#if defined (MPREAL_HAVE_CUSTOM_MPFR_MALLOC)
							 | 
						|
									// Optimized dynamic memory allocation/(re-)deallocation.
							 | 
						|
									void * mpreal::mpreal_allocate(size_t alloc_size)
							 | 
						|
									{
							 | 
						|
										return(dlmalloc(alloc_size));
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									void * mpreal::mpreal_reallocate(void *ptr, size_t old_size, size_t new_size)
							 | 
						|
									{
							 | 
						|
										return(dlrealloc(ptr,new_size));
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									void mpreal::mpreal_free(void *ptr, size_t size)
							 | 
						|
									{
							 | 
						|
										dlfree(ptr);
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									inline void mpreal::set_custom_malloc(void)
							 | 
						|
									{
							 | 
						|
										if(!is_custom_malloc)
							 | 
						|
										{
							 | 
						|
											mp_set_memory_functions(mpreal_allocate,mpreal_reallocate,mpreal_free);
							 | 
						|
											is_custom_malloc = true;
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								#endif
							 | 
						|
								
							 | 
						|
								}
							 | 
						|
								
							 |