[BACK]Return to mpfrxx.h CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp

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>