Annotation of OpenXM_contrib/gmp/mpfrxx.h, Revision 1.1
1.1 ! ohara 1: /* mpfrxx.h -- C++ class wrapper for MPFR. -*- C++ -*-
! 2:
! 3: Copyright 2001, 2002 Free Software Foundation, Inc.
! 4:
! 5: This file is part of the GNU MP Library.
! 6:
! 7: The GNU MP Library is free software; you can redistribute it and/or modify
! 8: it under the terms of the GNU Lesser General Public License as published by
! 9: the Free Software Foundation; either version 2.1 of the License, or (at your
! 10: option) any later version.
! 11:
! 12: The GNU MP Library is distributed in the hope that it will be useful, but
! 13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
! 15: License for more details.
! 16:
! 17: You should have received a copy of the GNU Lesser General Public License
! 18: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! 19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! 20: MA 02111-1307, USA. */
! 21:
! 22: #ifndef __GMPFR_PLUSPLUS__
! 23: #define __GMPFR_PLUSPLUS__
! 24:
! 25: #include <iostream>
! 26: #include <string>
! 27: #include <gmp.h>
! 28: #include <mpfr.h>
! 29: #include "gmpxx.h"
! 30:
! 31:
! 32: class __gmpfr_value { };
! 33:
! 34: template <class T, class U>
! 35: void __gmp_set_expr(mpfr_ptr, const __gmp_expr<T, U> &);
! 36:
! 37: const int mpfr_default_base = 10;
! 38:
! 39:
! 40: /**************** Macros for in-class declarations ****************/
! 41:
! 42: #define __GMPFRR_DECLARE_COMPOUND_OPERATOR(fun) \
! 43: template <class T, class U> \
! 44: __gmp_expr<__gmpfr_value, __gmpfr_value> & fun(const __gmp_expr<T, U> &);
! 45:
! 46: #define __GMPFRN_DECLARE_COMPOUND_OPERATOR(fun) \
! 47: __gmp_expr & fun(signed char); \
! 48: __gmp_expr & fun(unsigned char); \
! 49: __gmp_expr & fun(signed int); \
! 50: __gmp_expr & fun(unsigned int); \
! 51: __gmp_expr & fun(signed short int); \
! 52: __gmp_expr & fun(unsigned short int); \
! 53: __gmp_expr & fun(signed long int); \
! 54: __gmp_expr & fun(unsigned long int); \
! 55: __gmp_expr & fun(float); \
! 56: __gmp_expr & fun(double); \
! 57: __gmp_expr & fun(long double);
! 58:
! 59: #define __GMPFR_DECLARE_COMPOUND_OPERATOR(fun) \
! 60: __GMPFRR_DECLARE_COMPOUND_OPERATOR(fun) \
! 61: __GMPFRN_DECLARE_COMPOUND_OPERATOR(fun)
! 62:
! 63: #define __GMPFR_DECLARE_COMPOUND_OPERATOR_UI(fun) \
! 64: __gmp_expr & fun(unsigned long int);
! 65:
! 66: #define __GMPFR_DECLARE_INCREMENT_OPERATOR(fun) \
! 67: inline __gmp_expr & fun(); \
! 68: inline __gmp_expr fun(int);
! 69:
! 70:
! 71: /**************** mpfr_class -- wrapper for mpfr_t ****************/
! 72:
! 73: template <>
! 74: class __gmp_expr<__gmpfr_value, __gmpfr_value>
! 75: {
! 76: private:
! 77: mpfr_t mp;
! 78: public:
! 79: // size information
! 80: unsigned long int get_prec() const { return mpfr_get_prec(mp); }
! 81:
! 82: // constructors and destructor
! 83: __gmp_expr() { mpfr_init(mp); }
! 84:
! 85: __gmp_expr(const __gmp_expr &f)
! 86: {
! 87: mpfr_init2(mp, f.get_prec());
! 88: mpfr_set(mp, f.mp, __gmp_default_rounding_mode);
! 89: }
! 90: __gmp_expr(const __gmp_expr &f, unsigned long int prec,
! 91: mp_rnd_t mode = __gmp_default_rounding_mode)
! 92: { mpfr_init2(mp, prec); mpfr_set(mp, f.mp, mode); }
! 93: template <class T, class U>
! 94: __gmp_expr(const __gmp_expr<T, U> &expr)
! 95: { mpfr_init2(mp, expr.get_prec()); __gmp_set_expr(mp, expr); }
! 96: template <class T, class U>
! 97: __gmp_expr(const __gmp_expr<T, U> &expr, unsigned long int prec)
! 98: { mpfr_init2(mp, prec); __gmp_set_expr(mp, expr); }
! 99:
! 100: __gmp_expr(signed char c)
! 101: { mpfr_init(mp); mpfr_set_si(mp, c, __gmp_default_rounding_mode); }
! 102: __gmp_expr(signed char c, unsigned long int prec,
! 103: mp_rnd_t mode = __gmp_default_rounding_mode)
! 104: { mpfr_init2(mp, prec); mpfr_set_si(mp, c, mode); }
! 105: __gmp_expr(unsigned char c)
! 106: { mpfr_init(mp); mpfr_set_ui(mp, c, __gmp_default_rounding_mode); }
! 107: __gmp_expr(unsigned char c, unsigned long int prec,
! 108: mp_rnd_t mode = __gmp_default_rounding_mode)
! 109: { mpfr_init2(mp, prec); mpfr_set_ui(mp, c, mode); }
! 110:
! 111: __gmp_expr(signed int i)
! 112: { mpfr_init(mp); mpfr_set_si(mp, i, __gmp_default_rounding_mode); }
! 113: __gmp_expr(signed int i, unsigned long int prec,
! 114: mp_rnd_t mode = __gmp_default_rounding_mode)
! 115: { mpfr_init2(mp, prec); mpfr_set_si(mp, i, mode); }
! 116: __gmp_expr(unsigned int i)
! 117: { mpfr_init(mp); mpfr_set_ui(mp, i, __gmp_default_rounding_mode); }
! 118: __gmp_expr(unsigned int i, unsigned long int prec,
! 119: mp_rnd_t mode = __gmp_default_rounding_mode)
! 120: { mpfr_init2(mp, prec); mpfr_set_ui(mp, i, mode); }
! 121:
! 122: __gmp_expr(signed short int s)
! 123: { mpfr_init(mp); mpfr_set_si(mp, s, __gmp_default_rounding_mode); }
! 124: __gmp_expr(signed short int s, unsigned long int prec,
! 125: mp_rnd_t mode = __gmp_default_rounding_mode)
! 126: { mpfr_init2(mp, prec); mpfr_set_si(mp, s, mode); }
! 127: __gmp_expr(unsigned short int s)
! 128: { mpfr_init(mp); mpfr_set_ui(mp, s, __gmp_default_rounding_mode); }
! 129: __gmp_expr(unsigned short int s, unsigned long int prec,
! 130: mp_rnd_t mode = __gmp_default_rounding_mode)
! 131: { mpfr_init2(mp, prec); mpfr_set_ui(mp, s, mode); }
! 132:
! 133: __gmp_expr(signed long int l)
! 134: { mpfr_init(mp); mpfr_set_si(mp, l, __gmp_default_rounding_mode); }
! 135: __gmp_expr(signed long int l, unsigned long int prec,
! 136: mp_rnd_t mode = __gmp_default_rounding_mode)
! 137: { mpfr_init2(mp, prec); mpfr_set_si(mp, l, mode); }
! 138: __gmp_expr(unsigned long int l)
! 139: { mpfr_init(mp); mpfr_set_ui(mp, l, __gmp_default_rounding_mode); }
! 140: __gmp_expr(unsigned long int l, unsigned long int prec,
! 141: mp_rnd_t mode = __gmp_default_rounding_mode)
! 142: { mpfr_init2(mp, prec); mpfr_set_ui(mp, l, mode); }
! 143:
! 144: __gmp_expr(float f)
! 145: { mpfr_init(mp); mpfr_set_d(mp, f, __gmp_default_rounding_mode); }
! 146: __gmp_expr(float f, unsigned long int prec,
! 147: mp_rnd_t mode = __gmp_default_rounding_mode)
! 148: { mpfr_init2(mp, prec); mpfr_set_d(mp, f, mode); }
! 149: __gmp_expr(double d)
! 150: { mpfr_init(mp); mpfr_set_d(mp, d, __gmp_default_rounding_mode); }
! 151: __gmp_expr(double d, unsigned long int prec,
! 152: mp_rnd_t mode = __gmp_default_rounding_mode)
! 153: { mpfr_init2(mp, prec); mpfr_set_d(mp, d, mode); }
! 154: /*
! 155: __gmp_expr(long double ld)
! 156: { mpfr_init(mp); mpfr_set_d(mp, ld, __gmp_default_rounding_mode); }
! 157: __gmp_expr(long double ld, unsigned long int prec,
! 158: mp_rnd_t mode = __gmp_default_rounding_mode)
! 159: { mpfr_init2(mp, prec); mpfr_set_d(mp, ld, mode); }
! 160: */
! 161:
! 162: /*
! 163: explicit __gmp_expr(const char *s)
! 164: { mpfr_init_set_str(mp, s, mpfr_default_base); }
! 165: __gmp_expr(const char *s, int base) { mpfr_init_set_str(mp, s, base); }
! 166: explicit __gmp_expr(const std::string &s)
! 167: { mpfr_init_set_str(mp, s.c_str(), mpfr_default_base); }
! 168: __gmp_expr(const std::string &s, int base)
! 169: { mpfr_init_set_str(mp, s.c_str(), base); }
! 170: */
! 171:
! 172: explicit __gmp_expr(mpfr_srcptr f)
! 173: {
! 174: mpfr_init2(mp, mpfr_get_prec(f));
! 175: mpfr_set(mp, f, __gmp_default_rounding_mode);
! 176: }
! 177: explicit __gmp_expr(mpfr_srcptr f, unsigned long int prec)
! 178: {
! 179: mpfr_init2(mp, prec);
! 180: mpfr_set(mp, f, __gmp_default_rounding_mode);
! 181: }
! 182:
! 183: ~__gmp_expr() { mpfr_clear(mp); }
! 184:
! 185: // assignment operators
! 186: __gmp_expr & operator=(const __gmp_expr &f)
! 187: { mpfr_set(mp, f.mp, __gmp_default_rounding_mode); return *this; }
! 188: template <class T, class U>
! 189: __gmp_expr<__gmpfr_value, __gmpfr_value> & operator=
! 190: (const __gmp_expr<T, U> &expr)
! 191: { __gmp_set_expr(mp, expr); return *this; }
! 192:
! 193: __gmp_expr & operator=(signed char c)
! 194: { mpfr_set_si(mp, c, __gmp_default_rounding_mode); return *this; }
! 195: __gmp_expr & operator=(unsigned char c)
! 196: { mpfr_set_ui(mp, c, __gmp_default_rounding_mode); return *this; }
! 197:
! 198: __gmp_expr & operator=(signed int i)
! 199: { mpfr_set_si(mp, i, __gmp_default_rounding_mode); return *this; }
! 200: __gmp_expr & operator=(unsigned int i)
! 201: { mpfr_set_ui(mp, i, __gmp_default_rounding_mode); return *this; }
! 202:
! 203: __gmp_expr & operator=(signed short int s)
! 204: { mpfr_set_si(mp, s, __gmp_default_rounding_mode); return *this; }
! 205: __gmp_expr & operator=(unsigned short int s)
! 206: { mpfr_set_ui(mp, s, __gmp_default_rounding_mode); return *this; }
! 207:
! 208: __gmp_expr & operator=(signed long int l)
! 209: { mpfr_set_si(mp, l, __gmp_default_rounding_mode); return *this; }
! 210: __gmp_expr & operator=(unsigned long int l)
! 211: { mpfr_set_ui(mp, l, __gmp_default_rounding_mode); return *this; }
! 212:
! 213: __gmp_expr & operator=(float f)
! 214: { mpfr_set_d(mp, f, __gmp_default_rounding_mode); return *this; }
! 215: __gmp_expr & operator=(double d)
! 216: { mpfr_set_d(mp, d, __gmp_default_rounding_mode); return *this; }
! 217: /*
! 218: __gmp_expr & operator=(long double ld)
! 219: { mpfr_set_d(mp, ld, __gmp_default_rounding_mode); return *this; }
! 220: */
! 221:
! 222: /*
! 223: __gmp_expr & operator=(const char *s)
! 224: { mpfr_set_str(mp, s, mpfr_default_base); return *this; }
! 225: __gmp_expr & operator=(const std::string &s)
! 226: { mpfr_set_str(mp, s.c_str(), mpfr_default_base); return *this; }
! 227:
! 228: // string input/output functions
! 229: int set_str(const std::string &s, int base)
! 230: { return mpfr_set_str(mp, s.c_str(), base); }
! 231: */
! 232: std::string get_str(mp_exp_t *expo, int base, size_t size,
! 233: mp_rnd_t rmode = __gmp_default_rounding_mode) const
! 234: {
! 235: __gmp_alloc_cstring temp(mpfr_get_str(0, expo, base, size, mp, rmode));
! 236: return std::string(temp.str);
! 237: }
! 238:
! 239: // conversion functions
! 240: mpfr_srcptr get_mpfr_t() const { return mp; }
! 241: mpfr_ptr get_mpfr_t() { return mp; }
! 242:
! 243: // signed long get_si() const { return mpfr_get_si(mp); }
! 244: // unsigned long get_ui() const { return mpfr_get_ui(mp); }
! 245: double get_d() const // should be long double
! 246: { return mpfr_get_d(mp, __gmp_default_rounding_mode); }
! 247:
! 248: // compound assignments
! 249: __GMPFR_DECLARE_COMPOUND_OPERATOR(operator+=)
! 250: __GMPFR_DECLARE_COMPOUND_OPERATOR(operator-=)
! 251: __GMPFR_DECLARE_COMPOUND_OPERATOR(operator*=)
! 252: __GMPFR_DECLARE_COMPOUND_OPERATOR(operator/=)
! 253:
! 254: __GMPFR_DECLARE_COMPOUND_OPERATOR_UI(operator<<=)
! 255: __GMPFR_DECLARE_COMPOUND_OPERATOR_UI(operator>>=)
! 256:
! 257: __GMPFR_DECLARE_INCREMENT_OPERATOR(operator++)
! 258: __GMPFR_DECLARE_INCREMENT_OPERATOR(operator--)
! 259: };
! 260:
! 261: typedef __gmp_expr<__gmpfr_value, __gmpfr_value> mpfr_class;
! 262:
! 263:
! 264: inline std::ostream & operator<<(std::ostream &o, const mpfr_class &f)
! 265: {
! 266: mp_exp_t expo;
! 267: int base = 10;
! 268: __gmp_alloc_cstring temp(mpfr_get_str(0, &expo, base, 0, f.get_mpfr_t(),
! 269: __gmp_default_rounding_mode));
! 270:
! 271: // cancel terminating zeros
! 272: for (size_t i=strlen(temp.str)-1; temp.str[i]=='0' && i>0; --i)
! 273: temp.str[i] = '\0';
! 274:
! 275: if (*temp.str == '-')
! 276: o << "-0." << temp.str+1;
! 277: else
! 278: o << "0." << temp.str;
! 279:
! 280: if (base <= 10)
! 281: o << "e" << expo;
! 282: else
! 283: o << "@" << expo;
! 284:
! 285: return o;
! 286: }
! 287:
! 288: template <class T>
! 289: inline std::ostream & operator<<
! 290: (std::ostream &o, const __gmp_expr<__gmpfr_value, T> &expr)
! 291: {
! 292: mpfr_class temp(expr);
! 293: return o << temp;
! 294: }
! 295:
! 296: inline std::istream & operator>>(std::istream &i, mpfr_class &f)
! 297: {
! 298: mpf_t temp;
! 299: mpf_init2(temp, f.get_prec());
! 300: i >> temp;
! 301: mpfr_set_f(f.get_mpfr_t(), temp, __gmp_default_rounding_mode);
! 302: mpf_clear(temp);
! 303: return i;
! 304: }
! 305:
! 306:
! 307: /**************** Classes for type conversion ****************/
! 308:
! 309: class __gmpfr_temp
! 310: {
! 311: private:
! 312: mpfr_srcptr mp;
! 313: bool is_temp;
! 314: mpfr_t temp;
! 315:
! 316: __gmpfr_temp();
! 317: __gmpfr_temp(const __gmpfr_temp &);
! 318: void operator=(const __gmpfr_temp &);
! 319: public:
! 320: __gmpfr_temp(const mpfr_class &f) : mp(f.get_mpfr_t()), is_temp(false) { }
! 321: __gmpfr_temp(const mpfr_class &f, unsigned long int)
! 322: : mp(f.get_mpfr_t()), is_temp(false) { }
! 323: template <class T, class U>
! 324: __gmpfr_temp(const __gmp_expr<T, U> &expr)
! 325: {
! 326: mpfr_init2(temp, expr.get_prec());
! 327: __gmp_set_expr(temp, expr);
! 328: mp = temp;
! 329: is_temp = true;
! 330: }
! 331: template <class T, class U>
! 332: __gmpfr_temp(const __gmp_expr<T, U> &expr, unsigned long int prec)
! 333: {
! 334: mpfr_init2(temp, prec);
! 335: __gmp_set_expr(temp, expr);
! 336: mp = temp;
! 337: is_temp = true;
! 338: }
! 339: ~__gmpfr_temp() { if (is_temp) mpfr_clear(temp); }
! 340:
! 341: mpfr_srcptr get_mp() const { return mp; }
! 342: };
! 343:
! 344:
! 345: template <>
! 346: struct __gmp_resolve_expr<__gmpz_value, __gmpfr_value>
! 347: {
! 348: typedef __gmpfr_value value_type;
! 349: typedef __gmpfr_temp temp_type;
! 350: };
! 351:
! 352: template <>
! 353: struct __gmp_resolve_expr<__gmpfr_value, __gmpz_value>
! 354: {
! 355: typedef __gmpfr_value value_type;
! 356: typedef __gmpfr_temp temp_type;
! 357: };
! 358:
! 359: template <>
! 360: struct __gmp_resolve_expr<__gmpq_value, __gmpfr_value>
! 361: {
! 362: typedef __gmpfr_value value_type;
! 363: typedef __gmpfr_temp temp_type;
! 364: };
! 365:
! 366: template <>
! 367: struct __gmp_resolve_expr<__gmpfr_value, __gmpq_value>
! 368: {
! 369: typedef __gmpfr_value value_type;
! 370: typedef __gmpfr_temp temp_type;
! 371: };
! 372:
! 373: template <>
! 374: struct __gmp_resolve_expr<__gmpf_value, __gmpfr_value>
! 375: {
! 376: typedef __gmpfr_value value_type;
! 377: typedef __gmpfr_temp temp_type;
! 378: };
! 379:
! 380: template <>
! 381: struct __gmp_resolve_expr<__gmpfr_value, __gmpf_value>
! 382: {
! 383: typedef __gmpfr_value value_type;
! 384: typedef __gmpfr_temp temp_type;
! 385: };
! 386:
! 387: template <>
! 388: struct __gmp_resolve_expr<__gmpfr_value, __gmpfr_value>
! 389: {
! 390: typedef __gmpfr_value value_type;
! 391: typedef __gmpfr_temp temp_type;
! 392: };
! 393:
! 394:
! 395: /*
! 396: template <class T>
! 397: inline void __gmp_set_expr(mpz_ptr z, const mpfr_class &f)
! 398: {
! 399: mpz_set_fr(z, f.get_mpfr_t());
! 400: }
! 401:
! 402: template <class T>
! 403: inline void __gmp_set_expr
! 404: (mpz_ptr z, const __gmp_expr<__gmpfr_value, T> &expr)
! 405: {
! 406: mpfr_class temp(expr);
! 407: mpz_set_fr(z, temp.get_mpfr_t());
! 408: }
! 409:
! 410: template <class T>
! 411: inline void __gmp_set_expr(mpq_ptr q, const mpfr_class &f)
! 412: {
! 413: mpq_set_fr(q, f.get_mpfr_t());
! 414: }
! 415:
! 416: template <class T>
! 417: inline void __gmp_set_expr
! 418: (mpq_ptr q, const __gmp_expr<__gmpfr_value, T> &expr)
! 419: {
! 420: mpfr_class temp(expr);
! 421: mpq_set_fr(q, temp.get_mpfr_t());
! 422: }
! 423:
! 424: template <class T>
! 425: inline void __gmp_set_expr(mpf_ptr f, const mpfr_class &g)
! 426: {
! 427: mpf_set_fr(f, g.get_mpfr_t());
! 428: }
! 429:
! 430: template <class T>
! 431: inline void __gmp_set_expr
! 432: (mpf_ptr f, const __gmp_expr<__gmpfr_value, T> &expr)
! 433: {
! 434: mpfr_class temp(expr);
! 435: mpf_set_fr(f, temp.get_mpfr_t());
! 436: }
! 437: */
! 438:
! 439: template <class T>
! 440: inline void __gmp_set_expr(mpfr_ptr f, const mpz_class &z)
! 441: {
! 442: mpfr_set_z(f, z.get_mpz_t(), __gmp_default_rounding_mode);
! 443: }
! 444:
! 445: template <class T>
! 446: inline void __gmp_set_expr(mpfr_ptr f, const mpz_classref &z)
! 447: {
! 448: mpfr_set_z(f, z.get_mpz_t(), __gmp_default_rounding_mode);
! 449: }
! 450:
! 451: template <class T>
! 452: inline void __gmp_set_expr
! 453: (mpfr_ptr f, const __gmp_expr<__gmpz_value, T> &expr)
! 454: {
! 455: mpz_class temp(expr);
! 456: mpfr_set_z(f, temp.get_mpz_t(), __gmp_default_rounding_mode);
! 457: }
! 458:
! 459: template <class T>
! 460: inline void __gmp_set_expr(mpfr_ptr f, const mpq_class &q)
! 461: {
! 462: mpfr_set_q(f, q.get_mpq_t(), __gmp_default_rounding_mode);
! 463: }
! 464:
! 465: template <class T>
! 466: inline void __gmp_set_expr
! 467: (mpfr_ptr f, const __gmp_expr<__gmpq_value, T> &expr)
! 468: {
! 469: mpq_class temp(expr);
! 470: mpfr_set_q(f, temp.get_mpq_t(), __gmp_default_rounding_mode);
! 471: }
! 472:
! 473: template <class T>
! 474: inline void __gmp_set_expr(mpfr_ptr f, const mpf_class &g)
! 475: {
! 476: mpfr_set_f(f, g.get_mpf_t(), __gmp_default_rounding_mode);
! 477: }
! 478:
! 479: template <class T>
! 480: inline void __gmp_set_expr
! 481: (mpfr_ptr f, const __gmp_expr<__gmpf_value, T> &expr)
! 482: {
! 483: mpq_class temp(expr);
! 484: mpfr_set_f(f, temp.get_mpf_t(), __gmp_default_rounding_mode);
! 485: }
! 486:
! 487: template <>
! 488: inline void __gmp_set_expr(mpfr_ptr f, const mpfr_class &g)
! 489: {
! 490: mpfr_set(f, g.get_mpfr_t(), __gmp_default_rounding_mode);
! 491: }
! 492:
! 493: template <class T>
! 494: inline void __gmp_set_expr
! 495: (mpfr_ptr f, const __gmp_expr<__gmpfr_value, T> &expr)
! 496: {
! 497: expr.eval(f, mpfr_get_prec(f));
! 498: }
! 499:
! 500:
! 501: /**************** Specializations of __gmp_expr ****************/
! 502:
! 503: // unary expressions
! 504:
! 505: template <class Op>
! 506: class __gmp_expr<__gmpfr_value, __gmp_unary_expr<mpfr_class, Op> >
! 507: {
! 508: private:
! 509: __gmp_unary_expr<mpfr_class, Op> expr;
! 510: public:
! 511: __gmp_expr(const mpfr_class &val) : expr(val) { }
! 512: void eval(mpfr_ptr f, unsigned long int) const
! 513: { Op::eval(f, expr.val.get_mpfr_t(), __gmp_default_rounding_mode); }
! 514: unsigned long int get_prec() const
! 515: { return mpfr_get_prec(expr.val.get_mpfr_t()); }
! 516: };
! 517:
! 518: template <class T, class U, class Op>
! 519: class __gmp_expr<__gmpfr_value, __gmp_unary_expr<__gmp_expr<T, U>, Op> >
! 520: {
! 521: private:
! 522: __gmp_unary_expr<__gmp_expr<T, U>, Op> expr;
! 523: public:
! 524: __gmp_expr(const __gmp_expr<T, U> &val) : expr(val) { }
! 525: void eval(mpfr_ptr f, unsigned long int prec) const
! 526: {
! 527: mpfr_class temp(expr.val, prec);
! 528: Op::eval(f, temp.get_mpfr_t(), __gmp_default_rounding_mode);
! 529: }
! 530: unsigned long int get_prec() const { return expr.val.get_prec(); }
! 531: };
! 532:
! 533:
! 534: // binary expressions
! 535:
! 536: template <class Op>
! 537: class __gmp_expr
! 538: <__gmpfr_value, __gmp_binary_expr<mpfr_class, mpfr_class, Op> >
! 539: {
! 540: private:
! 541: __gmp_binary_expr<mpfr_class, mpfr_class, Op> expr;
! 542: public:
! 543: __gmp_expr(const mpfr_class &val1, const mpfr_class &val2)
! 544: : expr(val1, val2) { }
! 545: void eval(mpfr_ptr f, unsigned long int) const
! 546: { Op::eval(f, expr.val1.get_mpfr_t(), expr.val2.get_mpfr_t(),
! 547: __gmp_default_rounding_mode); }
! 548: unsigned long int get_prec() const
! 549: {
! 550: unsigned long int prec1 = expr.val1.get_prec(),
! 551: prec2 = expr.val2.get_prec();
! 552: return (prec1 > prec2) ? prec1 : prec2;
! 553: }
! 554: };
! 555:
! 556: template <class T, class Op>
! 557: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<mpfr_class, T, Op> >
! 558: {
! 559: private:
! 560: __gmp_binary_expr<mpfr_class, T, Op> expr;
! 561: public:
! 562: __gmp_expr(const mpfr_class &val1, T val2) : expr(val1, val2) { }
! 563: void eval(mpfr_ptr f, unsigned long int) const
! 564: { Op::eval(f, expr.val1.get_mpfr_t(), expr.val2,
! 565: __gmp_default_rounding_mode); }
! 566: unsigned long int get_prec() const
! 567: {
! 568: unsigned long int prec1 = expr.val1.get_prec(),
! 569: prec2 = mpf_get_default_prec();
! 570: return (prec1 > prec2) ? prec1 : prec2;
! 571: }
! 572: };
! 573:
! 574: template <class T, class Op>
! 575: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<T, mpfr_class, Op> >
! 576: {
! 577: private:
! 578: __gmp_binary_expr<T, mpfr_class, Op> expr;
! 579: public:
! 580: __gmp_expr(T val1, const mpfr_class &val2) : expr(val1, val2) { }
! 581: void eval(mpfr_ptr f, unsigned long int) const
! 582: { Op::eval(f, expr.val1, expr.val2.get_mpfr_t(),
! 583: __gmp_default_rounding_mode); }
! 584: unsigned long int get_prec() const
! 585: {
! 586: unsigned long int prec1 = mpf_get_default_prec(),
! 587: prec2 = expr.val2.get_prec();
! 588: return (prec1 > prec2) ? prec1 : prec2;
! 589: }
! 590: };
! 591:
! 592: template <class T, class U, class Op>
! 593: class __gmp_expr
! 594: <__gmpfr_value, __gmp_binary_expr<mpfr_class, __gmp_expr<T, U>, Op> >
! 595: {
! 596: private:
! 597: __gmp_binary_expr<mpfr_class, __gmp_expr<T, U>, Op> expr;
! 598: public:
! 599: __gmp_expr(const mpfr_class &val1, const __gmp_expr<T, U> &val2)
! 600: : expr(val1, val2) { }
! 601: void eval(mpfr_ptr f, unsigned long int prec) const
! 602: {
! 603: mpfr_class temp(expr.val2, prec);
! 604: Op::eval(f, expr.val1.get_mpfr_t(), temp.get_mpfr_t(),
! 605: __gmp_default_rounding_mode);
! 606: }
! 607: unsigned long int get_prec() const
! 608: {
! 609: unsigned long int prec1 = expr.val1.get_prec(),
! 610: prec2 = expr.val2.get_prec();
! 611: return (prec1 > prec2) ? prec1 : prec2;
! 612: }
! 613: };
! 614:
! 615: template <class T, class U, class Op>
! 616: class __gmp_expr
! 617: <__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, mpfr_class, Op> >
! 618: {
! 619: private:
! 620: __gmp_binary_expr<__gmp_expr<T, U>, mpfr_class, Op> expr;
! 621: public:
! 622: __gmp_expr(const __gmp_expr<T, U> &val1, const mpfr_class &val2)
! 623: : expr(val1, val2) { }
! 624: void eval(mpfr_ptr f, unsigned long int prec) const
! 625: {
! 626: mpfr_class temp(expr.val1, prec);
! 627: Op::eval(f, temp.get_mpfr_t(), expr.val2.get_mpfr_t(),
! 628: __gmp_default_rounding_mode);
! 629: }
! 630: unsigned long int get_prec() const
! 631: {
! 632: unsigned long int prec1 = expr.val1.get_prec(),
! 633: prec2 = expr.val2.get_prec();
! 634: return (prec1 > prec2) ? prec1 : prec2;
! 635: }
! 636: };
! 637:
! 638: template <class T, class U, class V, class Op>
! 639: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, V, Op> >
! 640: {
! 641: private:
! 642: __gmp_binary_expr<__gmp_expr<T, U>, V, Op> expr;
! 643: public:
! 644: __gmp_expr(const __gmp_expr<T, U> &val1, V val2) : expr(val1, val2) { }
! 645: void eval(mpfr_ptr f, unsigned long int prec) const
! 646: {
! 647: mpfr_class temp(expr.val1, prec);
! 648: Op::eval(f, temp.get_mpfr_t(), expr.val2, __gmp_default_rounding_mode);
! 649: }
! 650: unsigned long int get_prec() const
! 651: {
! 652: unsigned long int prec1 = expr.val1.get_prec(),
! 653: prec2 = mpf_get_default_prec();
! 654: return (prec1 > prec2) ? prec1 : prec2;
! 655: }
! 656: };
! 657:
! 658: template <class T, class U, class V, class Op>
! 659: class __gmp_expr<__gmpfr_value, __gmp_binary_expr<T, __gmp_expr<U, V>, Op> >
! 660: {
! 661: private:
! 662: __gmp_binary_expr<T, __gmp_expr<U, V>, Op> expr;
! 663: public:
! 664: __gmp_expr(T val1, const __gmp_expr<U, V> &val2) : expr(val1, val2) { }
! 665: void eval(mpfr_ptr f, unsigned long int prec) const
! 666: {
! 667: mpfr_class temp(expr.val2, prec);
! 668: Op::eval(f, expr.val1, temp.get_mpfr_t(), __gmp_default_rounding_mode);
! 669: }
! 670: unsigned long int get_prec() const
! 671: {
! 672: unsigned long int prec1 = mpf_get_default_prec(),
! 673: prec2 = expr.val2.get_prec();
! 674: return (prec1 > prec2) ? prec1 : prec2;
! 675: }
! 676: };
! 677:
! 678: template <class T, class U, class V, class W, class Op>
! 679: class __gmp_expr
! 680: <__gmpfr_value, __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> >
! 681: {
! 682: private:
! 683: __gmp_binary_expr<__gmp_expr<T, U>, __gmp_expr<V, W>, Op> expr;
! 684: public:
! 685: __gmp_expr(const __gmp_expr<T, U> &val1, const __gmp_expr<V, W> &val2)
! 686: : expr(val1, val2) { }
! 687: void eval(mpfr_ptr f, unsigned long int prec) const
! 688: {
! 689: mpfr_class temp1(expr.val1, prec), temp2(expr.val2, prec);
! 690: Op::eval(f, temp1.get_mpfr_t(), temp2.get_mpfr_t(),
! 691: __gmp_default_rounding_mode);
! 692: }
! 693: unsigned long int get_prec() const
! 694: {
! 695: unsigned long int prec1 = expr.val1.get_prec(),
! 696: prec2 = expr.val2.get_prec();
! 697: return (prec1 > prec2) ? prec1 : prec2;
! 698: }
! 699: };
! 700:
! 701:
! 702: /**************** Macros for defining functions ****************/
! 703:
! 704: #define __GMPFRR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
! 705: \
! 706: template <class T, class U> \
! 707: inline mpfr_class & mpfr_class::fun(const __gmp_expr<T, U> &expr) \
! 708: { \
! 709: __gmpfr_temp temp(expr, get_prec()); \
! 710: eval_fun::eval(mp, mp, temp.get_mp(), __gmp_default_rounding_mode); \
! 711: return *this; \
! 712: }
! 713:
! 714: #define __GMPFRN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
! 715: \
! 716: inline mpfr_class & mpfr_class::fun(signed char c) \
! 717: { \
! 718: eval_fun::eval(mp, mp, (signed long int) c, \
! 719: __gmp_default_rounding_mode); \
! 720: return *this; \
! 721: } \
! 722: \
! 723: inline mpfr_class & mpfr_class::fun(unsigned char c) \
! 724: { \
! 725: eval_fun::eval(mp, mp, (unsigned long int) c, \
! 726: __gmp_default_rounding_mode); \
! 727: return *this; \
! 728: } \
! 729: \
! 730: inline mpfr_class & mpfr_class::fun(signed int i) \
! 731: { \
! 732: eval_fun::eval(mp, mp, (signed long int) i, \
! 733: __gmp_default_rounding_mode); \
! 734: return *this; \
! 735: } \
! 736: \
! 737: inline mpfr_class & mpfr_class::fun(unsigned int i) \
! 738: { \
! 739: eval_fun::eval(mp, mp, (unsigned long int) i, \
! 740: __gmp_default_rounding_mode); \
! 741: return *this; \
! 742: } \
! 743: \
! 744: inline mpfr_class & mpfr_class::fun(signed short int s) \
! 745: { \
! 746: eval_fun::eval(mp, mp, (signed long int) s, \
! 747: __gmp_default_rounding_mode); \
! 748: return *this; \
! 749: } \
! 750: \
! 751: inline mpfr_class & mpfr_class::fun(unsigned short int s) \
! 752: { \
! 753: eval_fun::eval(mp, mp, (unsigned long int) s, \
! 754: __gmp_default_rounding_mode); \
! 755: return *this; \
! 756: } \
! 757: \
! 758: inline mpfr_class & mpfr_class::fun(signed long int l) \
! 759: { \
! 760: eval_fun::eval(mp, mp, l, __gmp_default_rounding_mode); \
! 761: return *this; \
! 762: } \
! 763: \
! 764: inline mpfr_class & mpfr_class::fun(unsigned long int l) \
! 765: { \
! 766: eval_fun::eval(mp, mp, l, __gmp_default_rounding_mode); \
! 767: return *this; \
! 768: } \
! 769: \
! 770: inline mpfr_class & mpfr_class::fun(float f) \
! 771: { \
! 772: eval_fun::eval(mp, mp, (double) f, __gmp_default_rounding_mode); \
! 773: return *this; \
! 774: } \
! 775: \
! 776: inline mpfr_class & mpfr_class::fun(double d) \
! 777: { \
! 778: eval_fun::eval(mp, mp, d, __gmp_default_rounding_mode); \
! 779: return *this; \
! 780: } \
! 781: \
! 782: /* \
! 783: inline mpfr_class & mpfr_class::fun(long double ld) \
! 784: { \
! 785: eval_fun::eval(mp, mp, ld, __gmp_default_rounding_mode); \
! 786: return *this; \
! 787: } */
! 788:
! 789: #define __GMPFR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
! 790: __GMPFRR_DEFINE_COMPOUND_OPERATOR(fun, eval_fun) \
! 791: __GMPFRN_DEFINE_COMPOUND_OPERATOR(fun, eval_fun)
! 792:
! 793: #define __GMPFR_DEFINE_COMPOUND_OPERATOR_UI(fun, eval_fun) \
! 794: \
! 795: inline mpfr_class & mpfr_class::fun(unsigned long int l) \
! 796: { \
! 797: eval_fun::eval(mp, mp, l, __gmp_default_rounding_mode); \
! 798: return *this; \
! 799: }
! 800:
! 801: #define __GMPFR_DEFINE_INCREMENT_OPERATOR(fun, eval_fun) \
! 802: \
! 803: inline mpfr_class & mpfr_class::fun() \
! 804: { \
! 805: eval_fun::eval(mp, mp, __gmp_default_rounding_mode); \
! 806: return *this; \
! 807: } \
! 808: \
! 809: inline mpfr_class mpfr_class::fun(int) \
! 810: { \
! 811: mpfr_class temp(*this); \
! 812: eval_fun::eval(mp, mp, __gmp_default_rounding_mode); \
! 813: return temp; \
! 814: }
! 815:
! 816:
! 817: /**************** Arithmetic operators and functions ****************/
! 818:
! 819: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator+=, __gmp_binary_plus)
! 820: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator-=, __gmp_binary_minus)
! 821: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator*=, __gmp_binary_multiplies)
! 822: __GMPFR_DEFINE_COMPOUND_OPERATOR(operator/=, __gmp_binary_divides)
! 823:
! 824: __GMPFR_DEFINE_COMPOUND_OPERATOR_UI(operator<<=, __gmp_binary_lshift)
! 825: __GMPFR_DEFINE_COMPOUND_OPERATOR_UI(operator>>=, __gmp_binary_rshift)
! 826:
! 827: __GMPFR_DEFINE_INCREMENT_OPERATOR(operator++, __gmp_unary_increment)
! 828: __GMPFR_DEFINE_INCREMENT_OPERATOR(operator--, __gmp_unary_decrement)
! 829:
! 830:
! 831: /**************** #undef all private macros ****************/
! 832:
! 833: #undef __GMPFRR_DECLARE_COMPOUND_OPERATOR
! 834: #undef __GMPFRN_DECLARE_COMPOUND_OPERATOR
! 835: #undef __GMPFR_DECLARE_COMPOUND_OPERATOR
! 836: #undef __GMPFR_DECLARE_COMPOUND_OPERATOR_UI
! 837: #undef __GMPFR_DECLARE_INCREMENT_OPERATOR
! 838:
! 839: #undef __GMPFRR_DEFINE_COMPOUND_OPERATOR
! 840: #undef __GMPFRN_DEFINE_COMPOUND_OPERATOR
! 841: #undef __GMPFR_DEFINE_COMPOUND_OPERATOR
! 842: #undef __GMPFR_DEFINE_COMPOUND_OPERATOR_UI
! 843: #undef __GMPFR_DEFINE_INCREMENT_OPERATOR
! 844:
! 845:
! 846: #endif /* __GMPFR_PLUSPLUS__ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>