From 375bc817cc093ab036933f3b240600d985c12653 Mon Sep 17 00:00:00 2001 From: Soonho Kong Date: Thu, 8 Aug 2013 20:20:53 -0700 Subject: [PATCH] Add more to mpfp --- src/util/numerics/double.h | 2 +- src/util/numerics/float.h | 2 +- src/util/numerics/mpbq.h | 46 +++++------ src/util/numerics/mpfp.cpp | 95 +--------------------- src/util/numerics/mpfp.h | 156 ++++++++++++++++++++++--------------- 5 files changed, 121 insertions(+), 180 deletions(-) diff --git a/src/util/numerics/double.h b/src/util/numerics/double.h index d1f6be2f3..df62d64fe 100644 --- a/src/util/numerics/double.h +++ b/src/util/numerics/double.h @@ -18,7 +18,7 @@ void double_power(double & v, unsigned k); // Macro to implement transcendental functions using MPFR #define LEAN_TRANS_DOUBLE_FUNC(f, v, rnd) \ - static thread_local mpfp t(v, 53); \ + static thread_local mpfp t(53); \ t = v; \ t.f(rnd); \ v = t.get_double(rnd); diff --git a/src/util/numerics/float.h b/src/util/numerics/float.h index 4e396d1d8..54e8bdcd7 100644 --- a/src/util/numerics/float.h +++ b/src/util/numerics/float.h @@ -18,7 +18,7 @@ void float_power(float & v, unsigned k); // Macro to implement transcendental functions using MPFR #define LEAN_TRANS_FLOAT_FUNC(f, v, rnd) \ - static thread_local mpfp t(v, 24); \ + static thread_local mpfp t(24); \ t = v; \ t.f(rnd); \ v = t.get_float(rnd); diff --git a/src/util/numerics/mpbq.h b/src/util/numerics/mpbq.h index 7bfa6d8ba..e4b1e0b7b 100644 --- a/src/util/numerics/mpbq.h +++ b/src/util/numerics/mpbq.h @@ -260,39 +260,41 @@ public: template<> class numeric_traits { +private: + static thread_local bool rnd; public: static bool precise() { return true; } static bool is_zero(mpbq const & v) { return v.is_zero(); } static bool is_pos(mpbq const & v) { return v.is_pos(); } static bool is_neg(mpbq const & v) { return v.is_neg(); } - static void set_rounding(bool plus_inf) {} + static void set_rounding(bool plus_inf) { rnd = plus_inf; } static void neg(mpbq & v) { v.neg(); } static void reset(mpbq & v) { v = 0; } // v <- v^k static void power(mpbq & v, unsigned k) { _power(v, v, k); } // Transcendental functions - static void exp(mpq & v) { lean_unreachable(); /* TODO */ } - static void exp2(mpq & v) { lean_unreachable(); /* TODO */ } - static void exp10(mpq & v) { lean_unreachable(); /* TODO */ } - static void log(mpq & v) { lean_unreachable(); /* TODO */ } - static void log2(mpq & v) { lean_unreachable(); /* TODO */ } - static void log10(mpq & v) { lean_unreachable(); /* TODO */ } - static void sin(mpq & v) { lean_unreachable(); /* TODO */ } - static void cos(mpq & v) { lean_unreachable(); /* TODO */ } - static void tan(mpq & v) { lean_unreachable(); /* TODO */ } - static void sec(mpq & v) { lean_unreachable(); /* TODO */ } - static void csc(mpq & v) { lean_unreachable(); /* TODO */ } - static void cot(mpq & v) { lean_unreachable(); /* TODO */ } - static void asin(mpq & v) { lean_unreachable(); /* TODO */ } - static void acos(mpq & v) { lean_unreachable(); /* TODO */ } - static void atan(mpq & v) { lean_unreachable(); /* TODO */ } - static void sinh(mpq & v) { lean_unreachable(); /* TODO */ } - static void cosh(mpq & v) { lean_unreachable(); /* TODO */ } - static void tanh(mpq & v) { lean_unreachable(); /* TODO */ } - static void asinh(mpq & v) { lean_unreachable(); /* TODO */ } - static void acosh(mpq & v) { lean_unreachable(); /* TODO */ } - static void atanh(mpq & v) { lean_unreachable(); /* TODO */ } + static void exp(mpbq & v) { lean_unreachable(); /* TODO */ } + static void exp2(mpbq & v) { lean_unreachable(); /* TODO */ } + static void exp10(mpbq & v) { lean_unreachable(); /* TODO */ } + static void log(mpbq & v) { lean_unreachable(); /* TODO */ } + static void log2(mpbq & v) { lean_unreachable(); /* TODO */ } + static void log10(mpbq & v) { lean_unreachable(); /* TODO */ } + static void sin(mpbq & v) { lean_unreachable(); /* TODO */ } + static void cos(mpbq & v) { lean_unreachable(); /* TODO */ } + static void tan(mpbq & v) { lean_unreachable(); /* TODO */ } + static void sec(mpbq & v) { lean_unreachable(); /* TODO */ } + static void csc(mpbq & v) { lean_unreachable(); /* TODO */ } + static void cot(mpbq & v) { lean_unreachable(); /* TODO */ } + static void asin(mpbq & v) { lean_unreachable(); /* TODO */ } + static void acos(mpbq & v) { lean_unreachable(); /* TODO */ } + static void atan(mpbq & v) { lean_unreachable(); /* TODO */ } + static void sinh(mpbq & v) { lean_unreachable(); /* TODO */ } + static void cosh(mpbq & v) { lean_unreachable(); /* TODO */ } + static void tanh(mpbq & v) { lean_unreachable(); /* TODO */ } + static void asinh(mpbq & v) { lean_unreachable(); /* TODO */ } + static void acosh(mpbq & v) { lean_unreachable(); /* TODO */ } + static void atanh(mpbq & v) { lean_unreachable(); /* TODO */ } }; } diff --git a/src/util/numerics/mpfp.cpp b/src/util/numerics/mpfp.cpp index c99f5cdaf..2dde22e9f 100644 --- a/src/util/numerics/mpfp.cpp +++ b/src/util/numerics/mpfp.cpp @@ -9,73 +9,6 @@ Author: Soonho Kong namespace lean { -// mpq & mpq::operator=(mpbq const & b) { -// *this = 2; -// power(*this, *this, b.get_k()); -// inv(); -// *this *= b.get_numerator(); -// return *this; -// } - -// int cmp(mpq const & a, mpz const & b) { -// if (a.is_integer()) { -// return mpz_cmp(mpq_numref(a.m_val), mpq::zval(b)); -// } -// else { -// static thread_local mpz tmp; -// mpz_mul(mpq::zval(tmp), mpq_denref(a.m_val), mpq::zval(b)); -// return mpz_cmp(mpq_numref(a.m_val), mpq::zval(tmp)); -// } -// } - -// void mpq::floor() { -// if (is_integer()) -// return; -// bool neg = is_neg(); -// mpz_tdiv_q(mpq_numref(m_val), mpq_numref(m_val), mpq_denref(m_val)); -// mpz_set_ui(mpq_denref(m_val), 1); -// if (neg) -// mpz_sub_ui(mpq_numref(m_val), mpq_numref(m_val), 1); -// } - -// void mpq::ceil() { -// if (is_integer()) -// return; -// bool pos = is_pos(); -// mpz_tdiv_q(mpq_numref(m_val), mpq_numref(m_val), mpq_denref(m_val)); -// mpz_set_ui(mpq_denref(m_val), 1); -// if (pos) -// mpz_add_ui(mpq_numref(m_val), mpq_numref(m_val), 1); -// } - -// mpz floor(mpq const & a) { -// if (a.is_integer()) -// return a.get_numerator(); -// mpz r; -// mpz_tdiv_q(mpq::zval(r), mpq_numref(a.m_val), mpq_denref(a.m_val)); -// if (a.is_neg()) -// --r; -// return r; -// } - -// mpz ceil(mpq const & a) { -// if (a.is_integer()) -// return a.get_numerator(); -// mpz r; -// mpz_tdiv_q(mpq::zval(r), mpq_numref(a.m_val), mpq_denref(a.m_val)); -// if (a.is_pos()) -// ++r; -// return r; -// } - -// void power(mpq & a, mpq const & b, unsigned k) { -// mpz_pow_ui(mpq_numref(a.m_val), mpq_numref(b.m_val), k); -// mpz_pow_ui(mpq_denref(a.m_val), mpq_denref(b.m_val), k); -// mpq_canonicalize(a.m_val); -// } - -// extern void display(std::ostream & out, __mpz_struct const * v); - inline unsigned necessary_digits(mpfr_prec_t p) { static constexpr double LOG10_2 = 0.30102999566; return std::ceil(p * LOG10_2) + 2; @@ -90,32 +23,6 @@ std::ostream & operator<<(std::ostream & out, mpfp const & v) { out << str; return out; } -// void display_decimal(std::ostream & out, mpq const & a, unsigned prec) { -// mpz n1, d1, v1; -// numerator(n1, a); -// denominator(d1, a); -// if (a.is_neg()) { -// out << "-"; -// neg(n1); -// } -// v1 = n1 / d1; -// out << v1; -// n1 = rem(n1, d1); -// if (n1.is_zero()) -// return; -// out << "."; -// for (unsigned i = 0; i < prec; i++) { -// n1 *= 10; -// v1 = n1 / d1; -// lean_assert(v1 < 10); -// out << v1; -// n1 = rem(n1, d1); -// if (n1.is_zero()) -// return; -// } -// out << "?"; -// } - } -// void print(lean::mpq const & v) { std::cout << v << std::endl; } +void print(lean::mpfp const & v) { std::cout << v << std::endl; } diff --git a/src/util/numerics/mpfp.h b/src/util/numerics/mpfp.h index 25dd319c7..e5583047f 100644 --- a/src/util/numerics/mpfp.h +++ b/src/util/numerics/mpfp.h @@ -19,12 +19,13 @@ class mpfp { friend numeric_traits; mpfr_t m_val; -// static mpfr_t const & zval(mpz const & v) { return v.m_val; } -// static mpfr_t & zval(mpz & v) { return v.m_val; } + static mpz_t const & zval(mpz const & v) { return v.m_val; } + static mpz_t & zval(mpz & v) { return v.m_val; } + static mpq_t const & qval(mpq const & v) { return v.m_val; } + static mpq_t & qval(mpq & v) { return v.m_val; } + public: - // friend void swap(mpfp & a, mpfp & b) { mpfr_swap(a.m_val, b.m_val); } - // friend void swap_numerator(mpfp & a, mpz & b) { mpz_swap(mpfr_numref(a.m_val), zval(b)); mpfr_canonicalize(a.m_val); } - // friend void swap_denominator(mpfp & a, mpz & b) { mpz_swap(mpfr_denref(a.m_val), zval(b)); mpfr_canonicalize(a.m_val); } + friend void swap(mpfp & a, mpfp & b) { mpfr_swap(a.m_val, b.m_val); } // Setter functions mpfp & set(mpfp const & v, mpfr_rnd_t rnd = MPFR_RNDN) { @@ -82,18 +83,20 @@ public: // Basic Constructors mpfp() { mpfr_init(m_val); } // with default precision - mpfp(mpfr_prec_t prec) { mpfr_init2(m_val, prec); } + explicit mpfp(int prec) { mpfr_init2(m_val, prec); } + explicit mpfp(unsigned prec) { mpfr_init2(m_val, prec); } + explicit mpfp(mpfr_prec_t prec) { mpfr_init2(m_val, prec); } // Constructors using the default precision - mpfp(float const v ):mpfp() { set(v); } - mpfp(double const v ):mpfp() { set(v); } - mpfp(long double const v):mpfp() { set(v); } - mpfp(mpz_t const & v ):mpfp() { set(v); } - mpfp(mpq_t const & v ):mpfp() { set(v); } - mpfp(mpf_t const & v ):mpfp() { set(v); } - mpfp(mpz const & v ):mpfp() { set(v); } - mpfp(mpq const & v ):mpfp() { set(v); } - mpfp(mpbq const & v ):mpfp() { set(v); } + explicit mpfp(float const v ):mpfp() { set(v); } + explicit mpfp(double const v ):mpfp() { set(v); } + explicit mpfp(long double const v):mpfp() { set(v); } + explicit mpfp(mpz_t const & v ):mpfp() { set(v); } + explicit mpfp(mpq_t const & v ):mpfp() { set(v); } + explicit mpfp(mpf_t const & v ):mpfp() { set(v); } + explicit mpfp(mpz const & v ):mpfp() { set(v); } + explicit mpfp(mpq const & v ):mpfp() { set(v); } + explicit mpfp(mpbq const & v ):mpfp() { set(v); } mpfp(mpfp const & v ):mpfp(mpfr_get_prec(v.m_val)) { set(v); } // Constructors using the provided precision @@ -120,9 +123,7 @@ public: mpfp(mpbq const & v , mpfr_prec_t p, mpfr_rnd_t rnd):mpfp(p) { set(v, rnd); } mpfp(mpfp const & v , mpfr_prec_t p, mpfr_rnd_t rnd):mpfp(p) { set(v, rnd); } - // mpfr(mpfp && s):mpfr() { mpfr_swap(m_val, s.m_val); } - // template explicit mpfr(T const & v):mpfr() { operator=(v); } - // mpfr(unsigned long int n, unsigned long int d):mpfr() { mpfr_set_ui(m_val, n, d); mpfr_canonicalize(m_val);} + mpfp(mpfp && s):mpfp(mpfr_get_prec(s.m_val)) { mpfr_swap(m_val, s.m_val); } ~mpfp() { mpfr_clear(m_val); } unsigned hash() const { return static_cast(mpfr_get_si(m_val, MPFR_RNDN)); } @@ -184,15 +185,12 @@ public: friend mpfp acosh(mpfp a, mpfr_rnd_t rnd = MPFR_RNDN) { a.acosh(rnd); return a; } friend mpfp atanh(mpfp a, mpfr_rnd_t rnd = MPFR_RNDN) { a.atanh(rnd); return a; } - // void inv() { mpfr_inv(m_val, m_val, MPFR_RNDN); } - // friend mpfp inv(mpfp a) { a.inv(); return a; } + void inv() { mpfr_d_div(m_val, 1.0, m_val, MPFR_RNDN); } + friend mpfp inv(mpfp a) { a.inv(); return a; } double get_double(mpfr_rnd_t rnd = MPFR_RNDN) const { return mpfr_get_d(m_val, rnd); } float get_float (mpfr_rnd_t rnd = MPFR_RNDN) const { return mpfr_get_flt(m_val, rnd); } - // bool is_integer() const { return mpz_cmp_ui(mpfr_denref(m_val), 1u) == 0; } - friend int cmp(mpfp const & a, mpfp const & b ) { return mpfr_cmp(a.m_val, b.m_val); } -// friend int cmp(mpfp const & a, mpz const & b); friend int cmp(mpfp const & a, unsigned long int const b) { return mpfr_cmp_ui(a.m_val, b); } friend int cmp(mpfp const & a, long int const b ) { return mpfr_cmp_si(a.m_val, b); } friend int cmp(mpfp const & a, double const b ) { return mpfr_cmp_d (a.m_val, b); } @@ -200,10 +198,9 @@ public: friend int cmp(mpfp const & a, mpz_t const & b ) { return mpfr_cmp_z (a.m_val, b); } friend int cmp(mpfp const & a, mpq_t const & b ) { return mpfr_cmp_q (a.m_val, b); } friend int cmp(mpfp const & a, mpf_t const & b ) { return mpfr_cmp_f (a.m_val, b); } - /* TODO */ - // friend int cmp(mpfp const & a, mpz const & b) { return mpfr_cmp_(a.m_val, b); } - // friend int cmp(mpfp const & a, mpq const & b) { return mpfr_cmp_(a.m_val, b); } - // friend int cmp(mpfp const & a, mpbq const & b) { return mpfr_cmp_(a.m_val, b); } + friend int cmp(mpfp const & a, mpz const & b ) { return mpfr_cmp_z (a.m_val, zval(b)); } + friend int cmp(mpfp const & a, mpq const & b ) { return mpfr_cmp_q (a.m_val, qval(b)); } + //friend int cmp(mpfp const & a, mpbq const & b) { return mpfr_cmp_(a.m_val, b); } friend bool operator<(mpfp const & a, mpfp const & b ) { return cmp(a, b) < 0; } friend bool operator<(mpfp const & a, mpz const & b ) { return cmp(a, b) < 0; } @@ -282,20 +279,38 @@ public: friend bool operator>=(mpf_t const & a , mpfp const & b) { return cmp(b, a) <= 0; } friend bool operator==(mpfp const & a, mpfp const & b) { return mpfr_equal_p(a.m_val, b.m_val) != 0; } -// friend bool operator==(mpfp const & a, mpz const & b) { return a.is_integer() && mpz_cmp(mpfr_numref(a.m_val), zval(b)) == 0; } - // friend bool operator==(mpfp const & a, unsigned int b) { return a.is_integer() && mpz_cmp_ui(mpfr_numref(a.m_val), b) == 0; } - // friend bool operator==(mpfp const & a, int b) { return a.is_integer() && mpz_cmp_si(mpfr_numref(a.m_val), b) == 0; } - // friend bool operator==(mpz const & a, mpfp const & b) { return operator==(b, a); } - // friend bool operator==(unsigned int a, mpfp const & b) { return operator==(b, a); } - // friend bool operator==(int a, mpfp const & b) { return operator==(b, a); } + friend bool operator==(unsigned long int const a, mpfp const & b) { return cmp(b, a) == 0; } + friend bool operator==(long int const a , mpfp const & b) { return cmp(b, a) == 0; } + friend bool operator==(double const a , mpfp const & b) { return cmp(b, a) == 0; } + friend bool operator==(long double const a , mpfp const & b) { return cmp(b, a) == 0; } + friend bool operator==(mpz_t const & a , mpfp const & b) { return cmp(b, a) == 0; } + friend bool operator==(mpq_t const & a , mpfp const & b) { return cmp(b, a) == 0; } + friend bool operator==(mpf_t const & a , mpfp const & b) { return cmp(b, a) == 0; } + friend bool operator==(mpfp const & a, mpz const & b ) { return cmp(a, b) == 0; } + friend bool operator==(mpfp const & a, unsigned long int const b) { return cmp(a, b) == 0; } + friend bool operator==(mpfp const & a, long int const b ) { return cmp(a, b) == 0; } + friend bool operator==(mpfp const & a, double const b ) { return cmp(a, b) == 0; } + friend bool operator==(mpfp const & a, long double const b ) { return cmp(a, b) == 0; } + friend bool operator==(mpfp const & a, mpz_t const & b ) { return cmp(a, b) == 0; } + friend bool operator==(mpfp const & a, mpq_t const & b ) { return cmp(a, b) == 0; } + friend bool operator==(mpfp const & a, mpf_t const & b ) { return cmp(a, b) == 0; } friend bool operator!=(mpfp const & a, mpfp const & b) { return !operator==(a,b); } - // friend bool operator!=(mpfp const & a, mpz const & b) { return !operator==(a,b); } - // friend bool operator!=(mpfp const & a, unsigned int b) { return !operator==(a,b); } - // friend bool operator!=(mpfp const & a, int b) { return !operator==(a,b); } - // friend bool operator!=(mpz const & a, mpfp const & b) { return !operator==(a,b); } - // friend bool operator!=(unsigned int a, mpfp const & b) { return !operator==(a,b); } - // friend bool operator!=(int a, mpfp const & b) { return !operator==(a,b); } + friend bool operator!=(unsigned long int const a, mpfp const & b) { return cmp(b, a) != 0; } + friend bool operator!=(long int const a , mpfp const & b) { return cmp(b, a) != 0; } + friend bool operator!=(double const a , mpfp const & b) { return cmp(b, a) != 0; } + friend bool operator!=(long double const a , mpfp const & b) { return cmp(b, a) != 0; } + friend bool operator!=(mpz_t const & a , mpfp const & b) { return cmp(b, a) != 0; } + friend bool operator!=(mpq_t const & a , mpfp const & b) { return cmp(b, a) != 0; } + friend bool operator!=(mpf_t const & a , mpfp const & b) { return cmp(b, a) != 0; } + friend bool operator!=(mpfp const & a, mpz const & b ) { return cmp(a, b) != 0; } + friend bool operator!=(mpfp const & a, unsigned long int const b) { return cmp(a, b) != 0; } + friend bool operator!=(mpfp const & a, long int const b ) { return cmp(a, b) != 0; } + friend bool operator!=(mpfp const & a, double const b ) { return cmp(a, b) != 0; } + friend bool operator!=(mpfp const & a, long double const b ) { return cmp(a, b) != 0; } + friend bool operator!=(mpfp const & a, mpz_t const & b ) { return cmp(a, b) != 0; } + friend bool operator!=(mpfp const & a, mpq_t const & b ) { return cmp(a, b) != 0; } + friend bool operator!=(mpfp const & a, mpf_t const & b ) { return cmp(a, b) != 0; } mpfp & add(mpfp const & o, mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_add(m_val, m_val, o.m_val, rnd); return *this; } mpfp & add(unsigned long int const o, mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_add_ui(m_val, m_val, o, rnd); return *this; } @@ -423,34 +438,51 @@ public: mpfp & operator^=(unsigned long int k) { return pow(k); } friend mpfp operator^(mpfp a, unsigned long int k) { return a ^= k; } - // mpfp & operator++() { return operator+=(1); } - // mpfp operator++(int) { mpfp r(*this); ++(*this); return r; } + mpfp & operator++() { return operator+=(1lu); } + mpfp operator++(int) { mpfp r(*this); ++(*this); return r; } - // mpfp & operator--() { return operator-=(1); } - // mpfp operator--(int) { mpfp r(*this); --(*this); return r; } + mpfp & operator--() { return operator-=(1lu); } + mpfp operator--(int) { mpfp r(*this); --(*this); return r; } - // void floor(); - // friend mpz floor(mpfp const & a); + void floor() { mpfr_floor(m_val, m_val); } + void ceil () { mpfr_ceil (m_val, m_val); } + void round() { mpfr_round(m_val, m_val); } + void trunc() { mpfr_trunc(m_val, m_val); } + void rfloor(mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_rint_floor(m_val, m_val, rnd); } + void rceil (mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_rint_ceil (m_val, m_val, rnd); } + void rround(mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_rint_round(m_val, m_val, rnd); } + void rtrunc(mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_rint_trunc(m_val, m_val, rnd); } - // void ceil(); - // friend mpz ceil(mpfp const & a); + friend mpfp floor(mpfp const & a) { static thread_local mpfp tmp; tmp = a; tmp.floor(); return tmp; } + friend mpfp ceil (mpfp const & a) { static thread_local mpfp tmp; tmp = a; tmp.ceil(); return tmp; } + friend mpfp round(mpfp const & a) { static thread_local mpfp tmp; tmp = a; tmp.round(); return tmp; } + friend mpfp trunc(mpfp const & a) { static thread_local mpfp tmp; tmp = a; tmp.trunc(); return tmp; } + friend mpfp rfloor(mpfp const & a, mpfr_rnd_t rnd = MPFR_RNDN) { + static thread_local mpfp tmp; tmp = a; tmp.rfloor(rnd); return tmp; + } + friend mpfp rceil (mpfp const & a, mpfr_rnd_t rnd = MPFR_RNDN) { + static thread_local mpfp tmp; tmp = a; tmp.rceil(rnd); return tmp; + } + friend mpfp rround(mpfp const & a, mpfr_rnd_t rnd = MPFR_RNDN) { + static thread_local mpfp tmp; tmp = a; tmp.rround(rnd); return tmp; + } + friend mpfp rtrunc(mpfp const & a, mpfr_rnd_t rnd = MPFR_RNDN) { + static thread_local mpfp tmp; tmp = a; tmp.rtrunc(rnd); return tmp; + } - // friend void power(mpfp & a, mpfp const & b, unsigned k); - // friend void _power(mpfp & a, mpfp const & b, unsigned k) { power(a, b, k); } - // friend mpfp power(mpfp a, unsigned k) { power(a, a, k); return a; } + void power(mpfp const & b, mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_pow(m_val, m_val, b.m_val, rnd); } + void power(unsigned long int b, mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_pow_ui(m_val, m_val, b, rnd); } + void power(long int b, mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_pow_si(m_val, m_val, b, rnd); } + void power(mpz_t const & b, mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_pow_z(m_val, m_val, b, rnd); } + void power(mpz const & b, mpfr_rnd_t rnd = MPFR_RNDN) { mpfr_pow_z(m_val, m_val, b.m_val, rnd); } + + friend mpfp power(mpfp a, mpfp const & b, mpfr_rnd_t rnd = MPFR_RNDN) { a.power(b, rnd); return a;; } + friend mpfp power(mpfp a, unsigned long int b, mpfr_rnd_t rnd = MPFR_RNDN) { a.power(b, rnd); return a;; } + friend mpfp power(mpfp a, long int b, mpfr_rnd_t rnd = MPFR_RNDN) { a.power(b, rnd); return a;; } + friend mpfp power(mpfp a, mpz_t const & b, mpfr_rnd_t rnd = MPFR_RNDN) { a.power(b, rnd); return a;; } + friend mpfp power(mpfp a, mpz const & b, mpfr_rnd_t rnd = MPFR_RNDN) { a.power(b, rnd); return a;; } friend std::ostream & operator<<(std::ostream & out, mpfp const & v); - - // friend void display_decimal(std::ostream & out, mpfp const & a, unsigned prec); - - // class decimal { - // mpfp const & m_val; - // unsigned m_prec; - // public: - // decimal(mpfp const & val, unsigned prec = 10):m_val(val), m_prec(prec) {} - // friend std::ostream & operator<<(std::ostream & out, decimal const & d) { display_decimal(out, d.m_val, d.m_prec); return out; } - // }; - }; // Macro to implement transcendental functions @@ -467,7 +499,7 @@ public: static void set_rounding(bool plus_inf) { rnd = plus_inf ? MPFR_RNDU :MPFR_RNDD; } static void neg(mpfp & v) { v.neg(); } // static void inv(mpfp & v) { v.inv(); } -// static void reset(mpfp & v) { v = 0; } + static void reset(mpfp & v) { v = 0.0; } // v <- v^k static void power(mpfp & v, unsigned k) { v.pow(k); }