#include "MpfrFloat.hh" #include #include #include #include #include #include //=========================================================================== // Auxiliary structs //=========================================================================== struct MpfrFloat::MpfrFloatData { unsigned mRefCount; MpfrFloatData* nextFreeNode; mpfr_t mFloat; MpfrFloatData(): mRefCount(1), nextFreeNode(0) {} }; class MpfrFloat::MpfrFloatDataContainer { unsigned long mDefaultPrecision; std::deque mData; MpfrFloatData* mFirstFreeNode; MpfrFloatData *mConst_0, *mConst_pi, *mConst_e, *mConst_log2, *mConst_epsilon; void recalculateEpsilon() { mpfr_set_si(mConst_epsilon->mFloat, 1, GMP_RNDN); mpfr_div_2ui(mConst_epsilon->mFloat, mConst_epsilon->mFloat, mDefaultPrecision*7/8 - 1, GMP_RNDN); } public: MpfrFloatDataContainer(): mDefaultPrecision(256), mFirstFreeNode(0), mConst_pi(0), mConst_e(0), mConst_log2(0), mConst_epsilon(0) {} ~MpfrFloatDataContainer() { for(size_t i = 0; i < mData.size(); ++i) mpfr_clear(mData[i].mFloat); } MpfrFloatData* allocateMpfrFloatData(bool initToZero) { if(mFirstFreeNode) { MpfrFloatData* node = mFirstFreeNode; mFirstFreeNode = node->nextFreeNode; if(initToZero) mpfr_set_si(node->mFloat, 0, GMP_RNDN); ++(node->mRefCount); return node; } mData.push_back(MpfrFloatData()); mpfr_init2(mData.back().mFloat, mDefaultPrecision); if(initToZero) mpfr_set_si(mData.back().mFloat, 0, GMP_RNDN); return &mData.back(); } void releaseMpfrFloatData(MpfrFloatData* data) { if(--(data->mRefCount) == 0) { data->nextFreeNode = mFirstFreeNode; mFirstFreeNode = data; } } void setDefaultPrecision(unsigned long bits) { if(bits != mDefaultPrecision) { mDefaultPrecision = bits; for(size_t i = 0; i < mData.size(); ++i) mpfr_prec_round(mData[i].mFloat, bits, GMP_RNDN); if(mConst_pi) mpfr_const_pi(mConst_pi->mFloat, GMP_RNDN); if(mConst_e) { mpfr_set_si(mConst_e->mFloat, 1, GMP_RNDN); mpfr_exp(mConst_e->mFloat, mConst_e->mFloat, GMP_RNDN); } if(mConst_log2) mpfr_const_log2(mConst_log2->mFloat, GMP_RNDN); if(mConst_epsilon) recalculateEpsilon(); } } unsigned long getDefaultPrecision() const { return mDefaultPrecision; } MpfrFloatData* const_0() { if(!mConst_0) mConst_0 = allocateMpfrFloatData(true); return mConst_0; } MpfrFloat const_pi() { if(!mConst_pi) { mConst_pi = allocateMpfrFloatData(false); mpfr_const_pi(mConst_pi->mFloat, GMP_RNDN); } return MpfrFloat(mConst_pi); } MpfrFloat const_e() { if(!mConst_e) { mConst_e = allocateMpfrFloatData(false); mpfr_set_si(mConst_e->mFloat, 1, GMP_RNDN); mpfr_exp(mConst_e->mFloat, mConst_e->mFloat, GMP_RNDN); } return MpfrFloat(mConst_e); } MpfrFloat const_log2() { if(!mConst_log2) { mConst_log2 = allocateMpfrFloatData(false); mpfr_const_log2(mConst_log2->mFloat, GMP_RNDN); } return MpfrFloat(mConst_log2); } MpfrFloat const_epsilon() { if(!mConst_epsilon) { mConst_epsilon = allocateMpfrFloatData(false); recalculateEpsilon(); } return MpfrFloat(mConst_epsilon); } }; //=========================================================================== // Shared data //=========================================================================== // This should ensure that the container is not accessed by any MpfrFloat // instance before it has been constructed or after it has been destroyed // (which might otherwise happen if MpfrFloat is instantiated globally.) MpfrFloat::MpfrFloatDataContainer& MpfrFloat::mpfrFloatDataContainer() { static MpfrFloat::MpfrFloatDataContainer container; return container; } //=========================================================================== // Auxiliary functions //=========================================================================== void MpfrFloat::setDefaultMantissaBits(unsigned long bits) { mpfrFloatDataContainer().setDefaultPrecision(bits); } unsigned long MpfrFloat::getCurrentDefaultMantissaBits() { return mpfrFloatDataContainer().getDefaultPrecision(); } inline void MpfrFloat::copyIfShared() { if(mData->mRefCount > 1) { --(mData->mRefCount); MpfrFloatData* oldData = mData; mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); mpfr_set(mData->mFloat, oldData->mFloat, GMP_RNDN); } } //=========================================================================== // Constructors, destructor, assignment //=========================================================================== MpfrFloat::MpfrFloat(DummyType): mData(mpfrFloatDataContainer().allocateMpfrFloatData(false)) {} MpfrFloat::MpfrFloat(MpfrFloatData* data): mData(data) { assert(data != 0); ++(mData->mRefCount); } MpfrFloat::MpfrFloat(): mData(mpfrFloatDataContainer().const_0()) { ++(mData->mRefCount); } MpfrFloat::MpfrFloat(double value) { if(value == 0.0) { mData = mpfrFloatDataContainer().const_0(); ++(mData->mRefCount); } else { mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); mpfr_set_d(mData->mFloat, value, GMP_RNDN); } } MpfrFloat::MpfrFloat(long double value) { if(value == 0.0L) { mData = mpfrFloatDataContainer().const_0(); ++(mData->mRefCount); } else { mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); mpfr_set_ld(mData->mFloat, value, GMP_RNDN); } } MpfrFloat::MpfrFloat(long value) { if(value == 0) { mData = mpfrFloatDataContainer().const_0(); ++(mData->mRefCount); } else { mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); mpfr_set_si(mData->mFloat, value, GMP_RNDN); } } MpfrFloat::MpfrFloat(int value) { if(value == 0) { mData = mpfrFloatDataContainer().const_0(); ++(mData->mRefCount); } else { mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); mpfr_set_si(mData->mFloat, value, GMP_RNDN); } } MpfrFloat::MpfrFloat(const char* value, char** endptr): mData(mpfrFloatDataContainer().allocateMpfrFloatData(false)) { mpfr_strtofr(mData->mFloat, value, endptr, 0, GMP_RNDN); } MpfrFloat::~MpfrFloat() { mpfrFloatDataContainer().releaseMpfrFloatData(mData); } MpfrFloat::MpfrFloat(const MpfrFloat& rhs): mData(rhs.mData) { ++(mData->mRefCount); } MpfrFloat& MpfrFloat::operator=(const MpfrFloat& rhs) { if(mData != rhs.mData) { mpfrFloatDataContainer().releaseMpfrFloatData(mData); mData = rhs.mData; ++(mData->mRefCount); } return *this; } MpfrFloat& MpfrFloat::operator=(double value) { if(value == 0.0) { mpfrFloatDataContainer().releaseMpfrFloatData(mData); mData = mpfrFloatDataContainer().const_0(); ++(mData->mRefCount); } else { if(mData->mRefCount > 1) { --(mData->mRefCount); mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); } mpfr_set_d(mData->mFloat, value, GMP_RNDN); } return *this; } MpfrFloat& MpfrFloat::operator=(long double value) { if(value == 0.0L) { mpfrFloatDataContainer().releaseMpfrFloatData(mData); mData = mpfrFloatDataContainer().const_0(); ++(mData->mRefCount); } else { if(mData->mRefCount > 1) { --(mData->mRefCount); mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); } mpfr_set_ld(mData->mFloat, value, GMP_RNDN); } return *this; } MpfrFloat& MpfrFloat::operator=(long value) { if(value == 0) { mpfrFloatDataContainer().releaseMpfrFloatData(mData); mData = mpfrFloatDataContainer().const_0(); ++(mData->mRefCount); } else { if(mData->mRefCount > 1) { --(mData->mRefCount); mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); } mpfr_set_si(mData->mFloat, value, GMP_RNDN); } return *this; } MpfrFloat& MpfrFloat::operator=(int value) { if(value == 0) { mpfrFloatDataContainer().releaseMpfrFloatData(mData); mData = mpfrFloatDataContainer().const_0(); ++(mData->mRefCount); } else { if(mData->mRefCount > 1) { --(mData->mRefCount); mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); } mpfr_set_si(mData->mFloat, value, GMP_RNDN); } return *this; } /* MpfrFloat& MpfrFloat::operator=(const char* value) { if(mData->mRefCount > 1) { --(mData->mRefCount); mData = mpfrFloatDataContainer().allocateMpfrFloatData(false); } mpfr_set_str(mData->mFloat, value, 10, GMP_RNDN); return *this; } */ void MpfrFloat::parseValue(const char* value) { copyIfShared(); mpfr_set_str(mData->mFloat, value, 10, GMP_RNDN); } void MpfrFloat::parseValue(const char* value, char** endptr) { copyIfShared(); mpfr_strtofr(mData->mFloat, value, endptr, 0, GMP_RNDN); } //=========================================================================== // Data getters //=========================================================================== template<> void MpfrFloat::get_raw_mpfr_data(mpfr_t& dest_mpfr_t) { std::memcpy(&dest_mpfr_t, mData->mFloat, sizeof(mpfr_t)); } const char* MpfrFloat::getAsString(unsigned precision) const { #if(MPFR_VERSION_MAJOR < 2 || (MPFR_VERSION_MAJOR == 2 && MPFR_VERSION_MINOR < 4)) static const char* retval = "[mpfr_snprintf() is not supported in mpfr versions prior to 2.4]"; return retval; #else static std::vector str; str.resize(precision+30); mpfr_snprintf(&(str[0]), precision+30, "%.*RNg", precision, mData->mFloat); return &(str[0]); #endif } bool MpfrFloat::isInteger() const { return mpfr_integer_p(mData->mFloat) != 0; } long MpfrFloat::toInt() const { return mpfr_get_si(mData->mFloat, GMP_RNDN); } double MpfrFloat::toDouble() const { return mpfr_get_d(mData->mFloat, GMP_RNDN); } //=========================================================================== // Modifying operators //=========================================================================== MpfrFloat& MpfrFloat::operator+=(const MpfrFloat& rhs) { copyIfShared(); mpfr_add(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return *this; } MpfrFloat& MpfrFloat::operator+=(double value) { copyIfShared(); mpfr_add_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); return *this; } MpfrFloat& MpfrFloat::operator-=(const MpfrFloat& rhs) { copyIfShared(); mpfr_sub(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return *this; } MpfrFloat& MpfrFloat::operator-=(double value) { copyIfShared(); mpfr_sub_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); return *this; } MpfrFloat& MpfrFloat::operator*=(const MpfrFloat& rhs) { copyIfShared(); mpfr_mul(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return *this; } MpfrFloat& MpfrFloat::operator*=(double value) { copyIfShared(); mpfr_mul_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); return *this; } MpfrFloat& MpfrFloat::operator/=(const MpfrFloat& rhs) { copyIfShared(); mpfr_div(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return *this; } MpfrFloat& MpfrFloat::operator/=(double value) { copyIfShared(); mpfr_div_d(mData->mFloat, mData->mFloat, value, GMP_RNDN); return *this; } MpfrFloat& MpfrFloat::operator%=(const MpfrFloat& rhs) { copyIfShared(); mpfr_fmod(mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return *this; } //=========================================================================== // Modifying functions //=========================================================================== void MpfrFloat::negate() { copyIfShared(); mpfr_neg(mData->mFloat, mData->mFloat, GMP_RNDN); } void MpfrFloat::abs() { copyIfShared(); mpfr_abs(mData->mFloat, mData->mFloat, GMP_RNDN); } //=========================================================================== // Non-modifying operators //=========================================================================== MpfrFloat MpfrFloat::operator+(const MpfrFloat& rhs) const { MpfrFloat retval(kNoInitialization); mpfr_add(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::operator+(double value) const { MpfrFloat retval(kNoInitialization); mpfr_add_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::operator-(const MpfrFloat& rhs) const { MpfrFloat retval(kNoInitialization); mpfr_sub(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::operator-(double value) const { MpfrFloat retval(kNoInitialization); mpfr_sub_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::operator*(const MpfrFloat& rhs) const { MpfrFloat retval(kNoInitialization); mpfr_mul(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::operator*(double value) const { MpfrFloat retval(kNoInitialization); mpfr_mul_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::operator/(const MpfrFloat& rhs) const { MpfrFloat retval(kNoInitialization); mpfr_div(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::operator/(double value) const { MpfrFloat retval(kNoInitialization); mpfr_div_d(retval.mData->mFloat, mData->mFloat, value, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::operator%(const MpfrFloat& rhs) const { MpfrFloat retval(kNoInitialization); mpfr_fmod(retval.mData->mFloat, mData->mFloat, rhs.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::operator-() const { MpfrFloat retval(kNoInitialization); mpfr_neg(retval.mData->mFloat, mData->mFloat, GMP_RNDN); return retval; } //=========================================================================== // Comparison operators //=========================================================================== bool MpfrFloat::operator<(const MpfrFloat& rhs) const { return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) < 0; } bool MpfrFloat::operator<(double value) const { return mpfr_cmp_d(mData->mFloat, value) < 0; } bool MpfrFloat::operator<=(const MpfrFloat& rhs) const { return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) <= 0; } bool MpfrFloat::operator<=(double value) const { return mpfr_cmp_d(mData->mFloat, value) <= 0; } bool MpfrFloat::operator>(const MpfrFloat& rhs) const { return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) > 0; } bool MpfrFloat::operator>(double value) const { return mpfr_cmp_d(mData->mFloat, value) > 0; } bool MpfrFloat::operator>=(const MpfrFloat& rhs) const { return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) >= 0; } bool MpfrFloat::operator>=(double value) const { return mpfr_cmp_d(mData->mFloat, value) >= 0; } bool MpfrFloat::operator==(const MpfrFloat& rhs) const { return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) == 0; } bool MpfrFloat::operator==(double value) const { return mpfr_cmp_d(mData->mFloat, value) == 0; } bool MpfrFloat::operator!=(const MpfrFloat& rhs) const { return mpfr_cmp(mData->mFloat, rhs.mData->mFloat) != 0; } bool MpfrFloat::operator!=(double value) const { return mpfr_cmp_d(mData->mFloat, value) != 0; } //=========================================================================== // Operator functions //=========================================================================== MpfrFloat operator+(double lhs, const MpfrFloat& rhs) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_add_d(retval.mData->mFloat, rhs.mData->mFloat, lhs, GMP_RNDN); return retval; } MpfrFloat operator-(double lhs, const MpfrFloat& rhs) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_d_sub(retval.mData->mFloat, lhs, rhs.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat operator*(double lhs, const MpfrFloat& rhs) { return rhs * lhs; } MpfrFloat operator/(double lhs, const MpfrFloat& rhs) { return MpfrFloat(lhs) / rhs; } MpfrFloat operator%(double lhs, const MpfrFloat& rhs) { return MpfrFloat(lhs) % rhs; } std::ostream& operator<<(std::ostream& os, const MpfrFloat& value) { os << value.getAsString(unsigned(os.precision())); return os; } //=========================================================================== // Static functions //=========================================================================== MpfrFloat MpfrFloat::log(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_log(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::log2(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_log2(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::log10(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_log10(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::exp(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_exp(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::exp2(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_exp2(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::exp10(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_exp10(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::cos(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_cos(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::sin(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_sin(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::tan(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_tan(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::sec(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_sec(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::csc(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_csc(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::cot(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_cot(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } void MpfrFloat::sincos(const MpfrFloat& value, MpfrFloat& sin, MpfrFloat& cos) { mpfr_sin_cos( sin.mData->mFloat, cos.mData->mFloat, value.mData->mFloat, GMP_RNDN); } MpfrFloat MpfrFloat::acos(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_acos(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::asin(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_asin(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::atan(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_atan(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::atan2(const MpfrFloat& value1, const MpfrFloat& value2) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_atan2(retval.mData->mFloat, value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::hypot(const MpfrFloat& value1, const MpfrFloat& value2) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_hypot(retval.mData->mFloat, value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::cosh(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_cosh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::sinh(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_sinh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::tanh(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_tanh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::acosh(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_acosh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::asinh(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_asinh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::atanh(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_atanh(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::sqrt(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_sqrt(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::cbrt(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_cbrt(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::root(const MpfrFloat& value, unsigned long root) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_root(retval.mData->mFloat, value.mData->mFloat, root, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::pow(const MpfrFloat& value1, const MpfrFloat& value2) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_pow(retval.mData->mFloat, value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::pow(const MpfrFloat& value, long exponent) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_pow_si(retval.mData->mFloat, value.mData->mFloat, exponent, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::abs(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_abs(retval.mData->mFloat, value.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::dim(const MpfrFloat& value1, const MpfrFloat& value2) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_dim(retval.mData->mFloat, value1.mData->mFloat, value2.mData->mFloat, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::round(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_round(retval.mData->mFloat, value.mData->mFloat); return retval; } MpfrFloat MpfrFloat::ceil(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_ceil(retval.mData->mFloat, value.mData->mFloat); return retval; } MpfrFloat MpfrFloat::floor(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_floor(retval.mData->mFloat, value.mData->mFloat); return retval; } MpfrFloat MpfrFloat::trunc(const MpfrFloat& value) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_trunc(retval.mData->mFloat, value.mData->mFloat); return retval; } MpfrFloat MpfrFloat::parseString(const char* str, char** endptr) { MpfrFloat retval(MpfrFloat::kNoInitialization); mpfr_strtofr(retval.mData->mFloat, str, endptr, 0, GMP_RNDN); return retval; } MpfrFloat MpfrFloat::const_pi() { return mpfrFloatDataContainer().const_pi(); } MpfrFloat MpfrFloat::const_e() { return mpfrFloatDataContainer().const_e(); } MpfrFloat MpfrFloat::const_log2() { return mpfrFloatDataContainer().const_log2(); } MpfrFloat MpfrFloat::someEpsilon() { return mpfrFloatDataContainer().const_epsilon(); }