mpreal.cpp
Go to the documentation of this file.
00001 /*
00002         Multi-precision real number class. C++ wrapper fo MPFR library.
00003         Project homepage: http://www.holoborodko.com/pavel/
00004         Contact e-mail:   pavel@holoborodko.com
00005 
00006         Copyright (c) 2008-2010 Pavel Holoborodko
00007 
00008         This library is free software; you can redistribute it and/or
00009         modify it under the terms of the GNU Lesser General Public
00010         License as published by the Free Software Foundation; either
00011         version 2.1 of the License, or (at your option) any later version.
00012 
00013         This library is distributed in the hope that it will be useful,
00014         but WITHOUT ANY WARRANTY; without even the implied warranty of
00015         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016         Lesser General Public License for more details.
00017 
00018         You should have received a copy of the GNU Lesser General Public
00019         License along with this library; if not, write to the Free Software
00020         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021 
00022         Contributors:
00023         Brian Gladman, Helmut Jarausch, Fokko Beekhof, Ulrich Mutze, 
00024         Heinz van Saanen, Pere Constans, Dmitriy Gubanov
00025 */
00026 
00027 #include <cstring>
00028 #include "mpreal.h"
00029 
00030 using std::ws;
00031 using std::cerr;
00032 using std::endl;
00033 using std::string;
00034 using std::ostream;
00035 using std::istream;
00036 
00037 namespace mpfr{
00038 
00039 mp_rnd_t   mpreal::default_rnd  = mpfr_get_default_rounding_mode();     
00040 mp_prec_t  mpreal::default_prec = mpfr_get_default_prec();      
00041 int                mpreal::default_base = 10;
00042 int        mpreal::double_bits = -1;
00043 
00044 // Default constructor: creates mp number and initializes it to 0.
00045 mpreal::mpreal() 
00046 { 
00047         mpfr_init2(mp,default_prec); 
00048         mpfr_set_ui(mp,0,default_rnd);
00049 }
00050 
00051 mpreal::mpreal(const mpreal& u) 
00052 {
00053         mpfr_init2(mp,mpfr_get_prec(u.mp));
00054         mpfr_set(mp,u.mp,default_rnd);
00055 }
00056 
00057 mpreal::mpreal(const mpfr_t u)
00058 {
00059         mpfr_init2(mp,mpfr_get_prec(u));
00060         mpfr_set(mp,u,default_rnd);
00061 }
00062 
00063 mpreal::mpreal(const mpf_t u)
00064 {
00065         mpfr_init2(mp,mpf_get_prec(u));
00066         mpfr_set_f(mp,u,default_rnd);
00067 }
00068 
00069 mpreal::mpreal(const mpz_t u, mp_prec_t prec, mp_rnd_t mode)
00070 {
00071         mpfr_init2(mp,prec);
00072         mpfr_set_z(mp,u,mode);
00073 }
00074 
00075 mpreal::mpreal(const mpq_t u, mp_prec_t prec, mp_rnd_t mode)
00076 {
00077         mpfr_init2(mp,prec);
00078         mpfr_set_q(mp,u,mode);
00079 }
00080 
00081 mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode)
00082 {
00083     if(double_bits == -1 || fits_in_bits(u, double_bits))
00084     {
00085         mpfr_init2(mp,prec);
00086             mpfr_set_d(mp,u,mode);
00087     }
00088     else
00089         throw conversion_overflow();
00090 }
00091 
00092 mpreal::mpreal(const long double u, mp_prec_t prec, mp_rnd_t mode)
00093 { 
00094     mpfr_init2(mp,prec);
00095         mpfr_set_ld(mp,u,mode);
00096 }
00097 
00098 mpreal::mpreal(const unsigned long int u, mp_prec_t prec, mp_rnd_t mode)
00099 { 
00100         mpfr_init2(mp,prec);
00101         mpfr_set_ui(mp,u,mode);
00102 }
00103 
00104 mpreal::mpreal(const unsigned int u, mp_prec_t prec, mp_rnd_t mode)
00105 { 
00106         mpfr_init2(mp,prec);
00107         mpfr_set_ui(mp,u,mode);
00108 }
00109 
00110 mpreal::mpreal(const long int u, mp_prec_t prec, mp_rnd_t mode)
00111 { 
00112         mpfr_init2(mp,prec);
00113         mpfr_set_si(mp,u,mode);
00114 }
00115 
00116 mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode)
00117 { 
00118         mpfr_init2(mp,prec);
00119         mpfr_set_si(mp,u,mode);
00120 }
00121 
00122 mpreal::mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode)
00123 {
00124         mpfr_init2(mp,prec);
00125         mpfr_set_str(mp, s, base, mode); 
00126 }
00127 
00128 mpreal::~mpreal() 
00129 { 
00130         mpfr_clear(mp); 
00131 }                           
00132 
00133 // Operators - Assignment
00134 mpreal& mpreal::operator=(const char* s)
00135 {
00136         mpfr_t t;
00137         if(0==mpfr_init_set_str(t,s,default_base,default_rnd))
00138         {
00139                 mpfr_set(mp,t,mpreal::default_rnd);                             
00140                 mpfr_clear(t);
00141         }else{
00142                 mpfr_clear(t);
00143                 // cerr<<"fail to convert string"<<endl;
00144         }
00145 
00146         return *this;
00147 }
00148 
00149 const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode)
00150 {
00151         mpreal a;
00152         mp_prec_t p1, p2, p3;
00153 
00154         p1 = v1.get_prec(); 
00155         p2 = v2.get_prec(); 
00156         p3 = v3.get_prec(); 
00157 
00158         a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
00159 
00160         mpfr_fma(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
00161         return a;
00162 }
00163 
00164 const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode)
00165 {
00166         mpreal a;
00167         mp_prec_t p1, p2, p3;
00168 
00169         p1 = v1.get_prec(); 
00170         p2 = v2.get_prec(); 
00171         p3 = v3.get_prec(); 
00172 
00173         a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
00174 
00175         mpfr_fms(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
00176         return a;
00177 }
00178 
00179 const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode)
00180 {
00181         mpreal a;
00182         mp_prec_t p1, p2;
00183 
00184         p1 = v1.get_prec(); 
00185         p2 = v2.get_prec(); 
00186 
00187         a.set_prec(p1>p2?p1:p2);
00188 
00189         mpfr_agm(a.mp, v1.mp, v2.mp, rnd_mode);
00190 
00191         return a;
00192 }
00193 
00194 const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
00195 {
00196         mpreal a;
00197         mp_prec_t yp, xp;
00198 
00199         yp = y.get_prec(); 
00200         xp = x.get_prec(); 
00201 
00202         a.set_prec(yp>xp?yp:xp);
00203 
00204         mpfr_hypot(a.mp, x.mp, y.mp, rnd_mode);
00205 
00206         return a;
00207 }
00208 
00209 const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode)
00210 {
00211         mpreal x;
00212         mpfr_ptr* t;
00213         unsigned long int i;
00214 
00215         t = new mpfr_ptr[n];
00216         for (i=0;i<n;i++) t[i] = (mpfr_ptr)tab[i].mp;
00217         mpfr_sum(x.mp,t,n,rnd_mode);
00218         delete[] t;
00219         return x;
00220 }
00221 
00222 const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
00223 {       
00224         mpreal a;
00225         mp_prec_t yp, xp;
00226 
00227         yp = y.get_prec(); 
00228         xp = x.get_prec(); 
00229 
00230         a.set_prec(yp>xp?yp:xp);
00231 
00232         mpfr_remainder(a.mp, x.mp, y.mp, rnd_mode);
00233 
00234         return a;
00235 }
00236 
00237 const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
00238 {
00239         mpreal a;
00240         mp_prec_t yp, xp;
00241 
00242         yp = y.get_prec(); 
00243         xp = x.get_prec(); 
00244 
00245         a.set_prec(yp>xp?yp:xp);
00246 
00247         mpfr_remquo(a.mp,q, x.mp, y.mp, rnd_mode);
00248 
00249         return a;
00250 }
00251 
00252 template <class T>
00253 std::string to_string(T t, std::ios_base & (*f)(std::ios_base&))
00254 {
00255         std::ostringstream oss;
00256         oss << f << t;
00257         return oss.str();
00258 }
00259 
00260 mpreal::operator std::string() const
00261 {
00262         return to_string();
00263 }
00264 
00265 string mpreal::to_string(size_t n, int b, mp_rnd_t mode) const
00266 {
00267         char *s, *ns = NULL;    
00268         size_t slen, nslen;
00269         mp_exp_t exp;
00270         string out;
00271 
00272         if(mpfr_inf_p(mp))
00273         { 
00274                 if(mpfr_sgn(mp)>0) return "+@Inf@";
00275                 else                       return "-@Inf@";
00276         }
00277 
00278         if(mpfr_zero_p(mp)) return "0";
00279         if(mpfr_nan_p(mp))  return "@NaN@";
00280 
00281                 
00282         s  = mpfr_get_str(NULL,&exp,b,0,mp,mode);
00283         ns = mpfr_get_str(NULL,&exp,b,n,mp,mode);
00284 
00285         if(s!=NULL && ns!=NULL)
00286         {
00287                 slen  = strlen(s);
00288                 nslen = strlen(ns);
00289                 if(nslen<=slen) 
00290                 {
00291                         mpfr_free_str(s);
00292                         s = ns;
00293                         slen = nslen;
00294                 }
00295                 else {
00296                         mpfr_free_str(ns);
00297                 }
00298 
00299                 // Make human eye-friendly formatting if possible
00300                 if (exp>0 && static_cast<size_t>(exp)<slen)
00301                 {
00302                         if(s[0]=='-')
00303                         {
00304                                 // Remove zeros starting from right end
00305                                 char* ptr = s+slen-1;
00306                                 while (*ptr=='0' && ptr>s+exp) ptr--; 
00307 
00308                                 if(ptr==s+exp) out = string(s,exp+1);
00309                                 else               out = string(s,exp+1)+'.'+string(s+exp+1,ptr-(s+exp+1)+1);
00310 
00311                                 //out = string(s,exp+1)+'.'+string(s+exp+1);
00312                         }
00313                         else
00314                         {
00315                                 // Remove zeros starting from right end
00316                                 char* ptr = s+slen-1;
00317                                 while (*ptr=='0' && ptr>s+exp-1) ptr--; 
00318 
00319                                 if(ptr==s+exp-1) out = string(s,exp);
00320                                 else                 out = string(s,exp)+'.'+string(s+exp,ptr-(s+exp)+1);
00321 
00322                                 //out = string(s,exp)+'.'+string(s+exp);
00323                         }
00324 
00325                 }else{ // exp<0 || exp>slen
00326                         if(s[0]=='-')
00327                         {
00328                                 // Remove zeros starting from right end
00329                                 char* ptr = s+slen-1;
00330                                 while (*ptr=='0' && ptr>s+1) ptr--; 
00331 
00332                                 if(ptr==s+1) out = string(s,2);
00333                                 else             out = string(s,2)+'.'+string(s+2,ptr-(s+2)+1);
00334 
00335                                 //out = string(s,2)+'.'+string(s+2);
00336                         }
00337                         else
00338                         {
00339                                 // Remove zeros starting from right end
00340                                 char* ptr = s+slen-1;
00341                                 while (*ptr=='0' && ptr>s) ptr--; 
00342 
00343                                 if(ptr==s) out = string(s,1);
00344                                 else       out = string(s,1)+'.'+string(s+1,ptr-(s+1)+1);
00345 
00346                                 //out = string(s,1)+'.'+string(s+1);
00347                         }
00348 
00349                         // Make final string
00350                         if(--exp)
00351                         {
00352                                 if(exp>0) out += "e+"+mpfr::to_string<mp_exp_t>(exp,std::dec);
00353                                 else      out += "e"+mpfr::to_string<mp_exp_t>(exp,std::dec);
00354                         }
00355                 }
00356 
00357                 mpfr_free_str(s);
00358                 return out;
00359         }else{
00360                 return "conversion error!";
00361         }
00362 }
00363 
00365 // I/O
00366 ostream& operator<<(ostream& os, const mpreal& v)
00367 {
00368         return os<<v.to_string(os.precision());
00369 }
00370 
00371 istream& operator>>(istream &is, mpreal& v)
00372 {
00373         char c; 
00374         string s = "";
00375         mpfr_t t;
00376 
00377         if(is.good())
00378         {
00379                 is>>ws;
00380                 while ((c = is.get())!=EOF)
00381                 {
00382                         if(c ==' ' || c == '\t' || c == '\n' || c == '\r')
00383                         {
00384                                 is.putback(c);
00385                                 break;
00386                         }
00387                         s += c;
00388                 }
00389 
00390                 if(s.size() != 0)
00391                 {
00392                         // Protect current value from alternation in case of input error
00393                         // so some error handling(roll back) procedure can be used 
00394                         if(0==mpfr_init_set_str(t,s.c_str(),mpreal::default_base,mpreal::default_rnd))
00395                         {
00396                                 mpfr_set(v.mp,t,mpreal::default_rnd);                           
00397                                 mpfr_clear(t);
00398 
00399                         }else{
00400                                 mpfr_clear(t);
00401                                 cerr<<"error reading from istream"<<endl;
00402                                 // throw an exception
00403                         }
00404                 }
00405         }
00406         return is;
00407 }
00408 }


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:00