00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #include <cstring>
00069 #include <cstdlib>
00070 #include "mpreal.h"
00071 #include "dlmalloc.h"
00072
00073 using std::ws;
00074 using std::cerr;
00075 using std::endl;
00076 using std::string;
00077 using std::ostream;
00078 using std::istream;
00079
00080 namespace mpfr{
00081
00082 mp_rnd_t mpreal::default_rnd = mpfr_get_default_rounding_mode();
00083 mp_prec_t mpreal::default_prec = mpfr_get_default_prec();
00084 int mpreal::default_base = 10;
00085 int mpreal::double_bits = -1;
00086 bool mpreal::is_custom_malloc = false;
00087
00088
00089 mpreal::mpreal()
00090 {
00091 set_custom_malloc();
00092 mpfr_init2(mp,default_prec);
00093 mpfr_set_ui(mp,0,default_rnd);
00094 }
00095
00096 mpreal::mpreal(const mpreal& u)
00097 {
00098 set_custom_malloc();
00099 mpfr_init2(mp,mpfr_get_prec(u.mp));
00100 mpfr_set(mp,u.mp,default_rnd);
00101 }
00102
00103 mpreal::mpreal(const mpfr_t u)
00104 {
00105 set_custom_malloc();
00106 mpfr_init2(mp,mpfr_get_prec(u));
00107 mpfr_set(mp,u,default_rnd);
00108 }
00109
00110 mpreal::mpreal(const mpf_t u)
00111 {
00112 set_custom_malloc();
00113 mpfr_init2(mp,mpf_get_prec(u));
00114 mpfr_set_f(mp,u,default_rnd);
00115 }
00116
00117 mpreal::mpreal(const mpz_t u, mp_prec_t prec, mp_rnd_t mode)
00118 {
00119 set_custom_malloc();
00120 mpfr_init2(mp,prec);
00121 mpfr_set_z(mp,u,mode);
00122 }
00123
00124 mpreal::mpreal(const mpq_t u, mp_prec_t prec, mp_rnd_t mode)
00125 {
00126 set_custom_malloc();
00127 mpfr_init2(mp,prec);
00128 mpfr_set_q(mp,u,mode);
00129 }
00130
00131 mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode)
00132 {
00133 set_custom_malloc();
00134 if(double_bits == -1 || fits_in_bits(u, double_bits))
00135 {
00136 mpfr_init2(mp,prec);
00137 mpfr_set_d(mp,u,mode);
00138 }
00139 else
00140 throw conversion_overflow();
00141 }
00142
00143 mpreal::mpreal(const long double u, mp_prec_t prec, mp_rnd_t mode)
00144 {
00145 set_custom_malloc();
00146 mpfr_init2(mp,prec);
00147 mpfr_set_ld(mp,u,mode);
00148 }
00149
00150 mpreal::mpreal(const unsigned long int u, mp_prec_t prec, mp_rnd_t mode)
00151 {
00152 set_custom_malloc();
00153 mpfr_init2(mp,prec);
00154 mpfr_set_ui(mp,u,mode);
00155 }
00156
00157 mpreal::mpreal(const unsigned int u, mp_prec_t prec, mp_rnd_t mode)
00158 {
00159 set_custom_malloc();
00160 mpfr_init2(mp,prec);
00161 mpfr_set_ui(mp,u,mode);
00162 }
00163
00164 mpreal::mpreal(const long int u, mp_prec_t prec, mp_rnd_t mode)
00165 {
00166 set_custom_malloc();
00167 mpfr_init2(mp,prec);
00168 mpfr_set_si(mp,u,mode);
00169 }
00170
00171 mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode)
00172 {
00173 set_custom_malloc();
00174 mpfr_init2(mp,prec);
00175 mpfr_set_si(mp,u,mode);
00176 }
00177
00178 mpreal::mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode)
00179 {
00180 set_custom_malloc();
00181 mpfr_init2(mp,prec);
00182 mpfr_set_str(mp, s, base, mode);
00183 }
00184
00185 mpreal::mpreal(const std::string& s, mp_prec_t prec, int base, mp_rnd_t mode)
00186 {
00187 set_custom_malloc();
00188 mpfr_init2(mp,prec);
00189 mpfr_set_str(mp, s.c_str(), base, mode);
00190 }
00191
00192 mpreal::~mpreal()
00193 {
00194 mpfr_clear(mp);
00195 }
00196
00197
00198 mpreal& mpreal::operator=(const char* s)
00199 {
00200 mpfr_t t;
00201
00202 set_custom_malloc();
00203
00204 if(0==mpfr_init_set_str(t,s,default_base,default_rnd))
00205 {
00206
00207 mpfr_set_prec(mp,mpfr_get_prec(t));
00208 mpfr_set(mp,t,mpreal::default_rnd);
00209 mpfr_clear(t);
00210 }else{
00211 mpfr_clear(t);
00212
00213 }
00214
00215 return *this;
00216 }
00217
00218 const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode)
00219 {
00220 mpreal a;
00221 mp_prec_t p1, p2, p3;
00222
00223 p1 = v1.get_prec();
00224 p2 = v2.get_prec();
00225 p3 = v3.get_prec();
00226
00227 a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
00228
00229 mpfr_fma(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
00230 return a;
00231 }
00232
00233 const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode)
00234 {
00235 mpreal a;
00236 mp_prec_t p1, p2, p3;
00237
00238 p1 = v1.get_prec();
00239 p2 = v2.get_prec();
00240 p3 = v3.get_prec();
00241
00242 a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
00243
00244 mpfr_fms(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
00245 return a;
00246 }
00247
00248 const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode)
00249 {
00250 mpreal a;
00251 mp_prec_t p1, p2;
00252
00253 p1 = v1.get_prec();
00254 p2 = v2.get_prec();
00255
00256 a.set_prec(p1>p2?p1:p2);
00257
00258 mpfr_agm(a.mp, v1.mp, v2.mp, rnd_mode);
00259
00260 return a;
00261 }
00262
00263 const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
00264 {
00265 mpreal a;
00266 mp_prec_t yp, xp;
00267
00268 yp = y.get_prec();
00269 xp = x.get_prec();
00270
00271 a.set_prec(yp>xp?yp:xp);
00272
00273 mpfr_hypot(a.mp, x.mp, y.mp, rnd_mode);
00274
00275 return a;
00276 }
00277
00278 const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode)
00279 {
00280 mpreal x;
00281 mpfr_ptr* t;
00282 unsigned long int i;
00283
00284 t = new mpfr_ptr[n];
00285 for (i=0;i<n;i++) t[i] = (mpfr_ptr)tab[i].mp;
00286 mpfr_sum(x.mp,t,n,rnd_mode);
00287 delete[] t;
00288 return x;
00289 }
00290
00291 const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
00292 {
00293 mpreal a;
00294 mp_prec_t yp, xp;
00295
00296 yp = y.get_prec();
00297 xp = x.get_prec();
00298
00299 a.set_prec(yp>xp?yp:xp);
00300
00301 mpfr_remainder(a.mp, x.mp, y.mp, rnd_mode);
00302
00303 return a;
00304 }
00305
00306 const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
00307 {
00308 mpreal a;
00309 mp_prec_t yp, xp;
00310
00311 yp = y.get_prec();
00312 xp = x.get_prec();
00313
00314 a.set_prec(yp>xp?yp:xp);
00315
00316 mpfr_remquo(a.mp,q, x.mp, y.mp, rnd_mode);
00317
00318 return a;
00319 }
00320
00321 template <class T>
00322 std::string to_string(T t, std::ios_base & (*f)(std::ios_base&))
00323 {
00324 std::ostringstream oss;
00325 oss << f << t;
00326 return oss.str();
00327 }
00328
00329 mpreal::operator std::string() const
00330 {
00331 return to_string();
00332 }
00333
00334 std::string mpreal::to_string(size_t n, int b, mp_rnd_t mode) const
00335 {
00336 char *s, *ns = NULL;
00337 size_t slen, nslen;
00338 mp_exp_t exp;
00339 string out;
00340
00341 set_custom_malloc();
00342
00343 if(mpfr_inf_p(mp))
00344 {
00345 if(mpfr_sgn(mp)>0) return "+@Inf@";
00346 else return "-@Inf@";
00347 }
00348
00349 if(mpfr_zero_p(mp)) return "0";
00350 if(mpfr_nan_p(mp)) return "@NaN@";
00351
00352 s = mpfr_get_str(NULL,&exp,b,0,mp,mode);
00353 ns = mpfr_get_str(NULL,&exp,b,n,mp,mode);
00354
00355 if(s!=NULL && ns!=NULL)
00356 {
00357 slen = strlen(s);
00358 nslen = strlen(ns);
00359 if(nslen<=slen)
00360 {
00361 mpfr_free_str(s);
00362 s = ns;
00363 slen = nslen;
00364 }
00365 else {
00366 mpfr_free_str(ns);
00367 }
00368
00369
00370 if (exp>0 && static_cast<size_t>(exp)<slen)
00371 {
00372 if(s[0]=='-')
00373 {
00374
00375 char* ptr = s+slen-1;
00376 while (*ptr=='0' && ptr>s+exp) ptr--;
00377
00378 if(ptr==s+exp) out = string(s,exp+1);
00379 else out = string(s,exp+1)+'.'+string(s+exp+1,ptr-(s+exp+1)+1);
00380
00381
00382 }
00383 else
00384 {
00385
00386 char* ptr = s+slen-1;
00387 while (*ptr=='0' && ptr>s+exp-1) ptr--;
00388
00389 if(ptr==s+exp-1) out = string(s,exp);
00390 else out = string(s,exp)+'.'+string(s+exp,ptr-(s+exp)+1);
00391
00392
00393 }
00394
00395 }else{
00396 if(s[0]=='-')
00397 {
00398
00399 char* ptr = s+slen-1;
00400 while (*ptr=='0' && ptr>s+1) ptr--;
00401
00402 if(ptr==s+1) out = string(s,2);
00403 else out = string(s,2)+'.'+string(s+2,ptr-(s+2)+1);
00404
00405
00406 }
00407 else
00408 {
00409
00410 char* ptr = s+slen-1;
00411 while (*ptr=='0' && ptr>s) ptr--;
00412
00413 if(ptr==s) out = string(s,1);
00414 else out = string(s,1)+'.'+string(s+1,ptr-(s+1)+1);
00415
00416
00417 }
00418
00419
00420 if(--exp)
00421 {
00422 if(exp>0) out += "e+"+mpfr::to_string<mp_exp_t>(exp,std::dec);
00423 else out += "e"+mpfr::to_string<mp_exp_t>(exp,std::dec);
00424 }
00425 }
00426
00427 mpfr_free_str(s);
00428 return out;
00429 }else{
00430 return "conversion error!";
00431 }
00432 }
00433
00435
00436 ostream& operator<<(ostream& os, const mpreal& v)
00437 {
00438 return os<<v.to_string(static_cast<size_t>(os.precision()));
00439 }
00440
00441 istream& operator>>(istream &is, mpreal& v)
00442 {
00443 char c;
00444 string s = "";
00445 mpfr_t t;
00446
00447 mpreal::set_custom_malloc();
00448
00449 if(is.good())
00450 {
00451 is>>ws;
00452 while ((c = is.get())!=EOF)
00453 {
00454 if(c ==' ' || c == '\t' || c == '\n' || c == '\r')
00455 {
00456 is.putback(c);
00457 break;
00458 }
00459 s += c;
00460 }
00461
00462 if(s.size() != 0)
00463 {
00464
00465
00466
00467 if(0==mpfr_init_set_str(t,s.c_str(),mpreal::default_base,mpreal::default_rnd))
00468 {
00469 mpfr_set(v.mp,t,mpreal::default_rnd);
00470 mpfr_clear(t);
00471
00472 }else{
00473 mpfr_clear(t);
00474 cerr<<"error reading from istream"<<endl;
00475
00476 }
00477 }
00478 }
00479 return is;
00480 }
00481
00482
00483 void * mpreal::mpreal_allocate(size_t alloc_size)
00484 {
00485 return(dlmalloc(alloc_size));
00486 }
00487
00488 void * mpreal::mpreal_reallocate(void *ptr, size_t , size_t new_size)
00489 {
00490 return(dlrealloc(ptr,new_size));
00491 }
00492
00493 void mpreal::mpreal_free(void *ptr, size_t )
00494 {
00495 dlfree(ptr);
00496 }
00497
00498 inline void mpreal::set_custom_malloc(void)
00499 {
00500 if(!is_custom_malloc)
00501 {
00502 mp_set_memory_functions(mpreal_allocate,mpreal_reallocate,mpreal_free);
00503 is_custom_malloc = true;
00504 }
00505 }
00506 }
00507