From c8eda6845ee1e4d422c4b212cb862b40591cd58f Mon Sep 17 00:00:00 2001 From: John Maddock Date: Sat, 12 Nov 2011 13:15:33 +0000 Subject: [PATCH] Search and replace - rename mp_float cpp_float. [SVN r75453] --- example/mp_float_snips.cpp | 10 +- include/boost/multiprecision/cpp_float.hpp | 2726 ++++++++++++++++++++ include/boost/multiprecision/mp_float.hpp | 986 +++---- test/Jamfile.v2 | 66 +- test/linpack-benchmark.cpp | 16 +- test/mp_number_concept_check.cpp | 18 +- test/test_acos.cpp | 14 +- test/test_arithmetic.cpp | 12 +- test/test_asin.cpp | 14 +- test/test_atan.cpp | 14 +- test/test_cos.cpp | 14 +- test/test_cosh.cpp | 14 +- test/test_exp.cpp | 14 +- test/test_fpclassify.cpp | 14 +- test/test_log.cpp | 18 +- test/test_numeric_limits.cpp | 14 +- test/test_pow.cpp | 14 +- test/test_round.cpp | 14 +- test/test_sin.cpp | 17 +- test/test_sinh.cpp | 14 +- test/test_tanh.cpp | 14 +- 21 files changed, 3386 insertions(+), 651 deletions(-) create mode 100644 include/boost/multiprecision/cpp_float.hpp diff --git a/example/mp_float_snips.cpp b/example/mp_float_snips.cpp index 0b2df0d0..8d3e5c25 100644 --- a/example/mp_float_snips.cpp +++ b/example/mp_float_snips.cpp @@ -3,19 +3,19 @@ // Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ -#include +#include #include void t1() { - //[mp_float_eg - //=#include + //[cpp_float_eg + //=#include using namespace boost::multiprecision; // Operations at fixed precision and full numeric_limits support: - mp_float_100 b = 2; - std::cout << std::numeric_limits::digits << std::endl; + cpp_float_100 b = 2; + std::cout << std::numeric_limits::digits << std::endl; std::cout << log(b) << std::endl; // print log(2) //] } diff --git a/include/boost/multiprecision/cpp_float.hpp b/include/boost/multiprecision/cpp_float.hpp new file mode 100644 index 00000000..13c41251 --- /dev/null +++ b/include/boost/multiprecision/cpp_float.hpp @@ -0,0 +1,2726 @@ +/////////////////////////////////////////////////////////////////////////////// +// Copyright Christopher Kormanyos 2002 - 2011. +// Copyright 2011 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// This work is based on an earlier work: +// "Algorithm 910: A Portable C++ Multiple-Precision System for Special-Function Calculations", +// in ACM TOMS, {VOL 37, ISSUE 4, (February 2011)} (C) ACM, 2011. http://doi.acm.org/10.1145/1916461.1916469 +// + +#ifndef BOOST_MP_EFX_BACKEND_HPP +#define BOOST_MP_EFX_BACKEND_HPP + +#include +#include +#include + +// +// Headers required for Boost.Math integration: +// +#include + +namespace boost{ +namespace multiprecision{ + +template +class cpp_float +{ +public: + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; + typedef mpl::list real_types; + typedef boost::int64_t exponent_type; + + + static const boost::int32_t mp_radix = 10; + static const boost::int32_t cpp_float_digits = Digits10; + + static const boost::int32_t cpp_float_digits10_setting = Digits10; + static const boost::int32_t cpp_float_digits10_limit = boost::integer_traits::const_max; + static const boost::int32_t cpp_float_digits10 = ((cpp_float_digits10_setting < static_cast(30)) ? static_cast(30) : ((cpp_float_digits10_setting > cpp_float_digits10_limit) ? cpp_float_digits10_limit : cpp_float_digits10_setting)); + static const boost::int32_t cpp_float_digits10_extra = static_cast(((static_cast(cpp_float_digits10) * 15LL) + 50LL) / 100LL); + static const boost::int32_t cpp_float_max_digits10 = static_cast(cpp_float_digits10 + ((cpp_float_digits10_extra < static_cast(5)) ? static_cast(5) : ((cpp_float_digits10_extra > static_cast(30)) ? static_cast(30) : cpp_float_digits10_extra))); + static const boost::int64_t cpp_float_max_exp = static_cast(+9223372036854775795LL); + static const boost::int64_t cpp_float_min_exp = static_cast(-9223372036854775795LL); + static const boost::int64_t cpp_float_max_exp10 = static_cast(+3063937869882635616LL); // Approx. [cpp_float_max_exp / log10(2)], also an even multiple of 8 + static const boost::int64_t cpp_float_min_exp10 = static_cast(-3063937869882635616LL); + static const boost::int32_t mp_elem_digits10 = static_cast(8); + +private: + static const boost::int32_t cpp_float_digits10_num_base = static_cast((cpp_float_max_digits10 / mp_elem_digits10) + (((cpp_float_max_digits10 % mp_elem_digits10) != 0) ? 1 : 0)); + static const boost::int32_t mp_elem_number = static_cast(cpp_float_digits10_num_base + 2); + static const boost::int32_t mp_elem_mask = static_cast(100000000); + + typedef enum enum_fpclass + { + mp_finite, + mp_inf, + mp_NaN + } + t_fpclass; + + typedef boost::array array_type; + + array_type data; + boost::int64_t exp; + bool neg; + t_fpclass fpclass; + boost::int32_t prec_elem; + + // + // Special values constructor: + // + cpp_float(t_fpclass c) : + data(), + exp (static_cast(0)), + neg (false), + fpclass (c), + prec_elem(mp_elem_number) { } + + // + // Static data initializer: + // + struct initializer + { + initializer() + { + cpp_float::nan(); + cpp_float::inf(); + (cpp_float::min)(); + (cpp_float::max)(); + cpp_float::zero(); + cpp_float::one(); + cpp_float::two(); + cpp_float::half(); + cpp_float::double_min(); + cpp_float::double_max(); + cpp_float::long_double_max(); + cpp_float::long_double_min(); + cpp_float::long_long_max(); + cpp_float::long_long_min(); + cpp_float::ulong_long_max(); + cpp_float::eps(); + cpp_float::pow2(0); + } + void do_nothing(){} + }; + + static initializer init; + +public: + // Constructors + cpp_float() : + data(), + exp (static_cast(0)), + neg (false), + fpclass (mp_finite), + prec_elem(mp_elem_number) { } + + cpp_float(const char* s) : + data(), + exp (static_cast(0)), + neg (false), + fpclass (mp_finite), + prec_elem(mp_elem_number) + { + *this = s; + } + + template + cpp_float(I i, typename enable_if >::type* = 0) : + data(), + exp (static_cast(0)), + neg (false), + fpclass (mp_finite), + prec_elem(mp_elem_number) + { + from_unsigned_long_long(i); + } + + template + cpp_float(I i, typename enable_if >::type* = 0) : + data(), + exp (static_cast(0)), + neg (false), + fpclass (mp_finite), + prec_elem(mp_elem_number) + { + if(i < 0) + { + from_unsigned_long_long(-i); + negate(); + } + else + from_unsigned_long_long(i); + } + + cpp_float(const cpp_float& f) : + data (f.data), + exp (f.exp), + neg (f.neg), + fpclass (f.fpclass), + prec_elem(f.prec_elem) { } + + template + cpp_float(const F val, typename enable_if >::type* = 0): + data(), + exp (static_cast(0)), + neg (false), + fpclass (mp_finite), + prec_elem(mp_elem_number) + { + *this = val; + } + + cpp_float(const double val, long long exponent); + + // Specific special values. + static const cpp_float& nan() + { + static const cpp_float val(mp_NaN); + init.do_nothing(); + return val; + } + static const cpp_float& inf() + { + static const cpp_float val(mp_inf); + init.do_nothing(); + return val; + } + static const cpp_float& (max)() + { + init.do_nothing(); + static bool init = false; + static const std::string str_max = std::string("9." + std::string(static_cast(cpp_float_max_digits10), static_cast('9'))) + + std::string("e+" + boost::lexical_cast(cpp_float_max_exp10)); + static cpp_float val_max; + if(!init) + { + init = true; + val_max = str_max.c_str(); + } + return val_max; + } + + static const cpp_float& (min)() + { + init.do_nothing(); + static bool init = false; + static cpp_float val_min; + if(!init) + { + init = true; + val_min = std::string("1.0e" + boost::lexical_cast(cpp_float_min_exp10)).c_str(); + } + return val_min; + } + static const cpp_float& zero() + { + init.do_nothing(); + static cpp_float val(static_cast(0u)); + return val; + } + static const cpp_float& one() + { + init.do_nothing(); + static cpp_float val(static_cast(1u)); + return val; + } + static const cpp_float& two() + { + init.do_nothing(); + static cpp_float val(static_cast(2u)); + return val; + } + static const cpp_float& half() + { + init.do_nothing(); + static cpp_float val(0.5L); + return val; + } + static const cpp_float& double_min() + { + init.do_nothing(); + static cpp_float val(static_cast((std::numeric_limits::min)())); + return val; + } + static const cpp_float& double_max() + { + init.do_nothing(); + static cpp_float val(static_cast((std::numeric_limits::max)())); + return val; + } + static const cpp_float& long_double_min() + { + init.do_nothing(); + static cpp_float val((std::numeric_limits::min)()); + return val; + } + static const cpp_float& long_double_max() + { + init.do_nothing(); + static cpp_float val((std::numeric_limits::max)()); + return val; + } + static const cpp_float& long_long_max() + { + init.do_nothing(); + static cpp_float val((std::numeric_limits::max)()); + return val; + } + static const cpp_float& long_long_min() + { + init.do_nothing(); + static cpp_float val((std::numeric_limits::min)()); + return val; + } + static const cpp_float& ulong_long_max() + { + init.do_nothing(); + static cpp_float val((std::numeric_limits::max)()); + return val; + } + static const cpp_float& eps() + { + init.do_nothing(); + static cpp_float val(1.0, 1 - (int)Digits10); + return val; + } + + // Basic operations. + cpp_float& operator= (const cpp_float& v) + { + data = v.data; + exp = v.exp; + neg = v.neg; + fpclass = v.fpclass; + prec_elem = v.prec_elem; + return *this; + } + cpp_float& operator= (long long v) + { + if(v < 0) + { + from_unsigned_long_long(-v); + negate(); + } + else + from_unsigned_long_long(v); + return *this; + } + cpp_float& operator= (unsigned long long v) + { + from_unsigned_long_long(v); + return *this; + } + cpp_float& operator= (long double v); + cpp_float& operator= (const char* v) + { + rd_string(v); + return *this; + } + + cpp_float& operator+=(const cpp_float& v); + cpp_float& operator-=(const cpp_float& v); + cpp_float& operator*=(const cpp_float& v); + cpp_float& operator/=(const cpp_float& v); + + cpp_float& add_unsigned_long_long(const unsigned long long n) + { + cpp_float t; + t.from_unsigned_long_long(n); + return *this += t; + } + cpp_float& sub_unsigned_long_long(const unsigned long long n) + { + cpp_float t; + t.from_unsigned_long_long(n); + return *this -= t; + } + cpp_float& mul_unsigned_long_long(const unsigned long long n); + cpp_float& div_unsigned_long_long(const unsigned long long n); + + // Elementary primitives. + cpp_float& calculate_inv (void); + cpp_float& calculate_sqrt(void); + void negate() + { + if(!iszero()) + neg = !neg; + } + + // Comparison functions + bool isnan (void) const { return (fpclass == mp_NaN); } + bool isinf (void) const { return (fpclass == mp_inf); } + bool isfinite(void) const { return (fpclass == mp_finite); } + + bool iszero (void) const + { + return ((fpclass == mp_finite) && (data[0u] == 0u)); + } + bool isone (void) const; + bool isint (void) const; + bool isneg (void) const { return neg; } + + // Operators pre-increment and pre-decrement + cpp_float& operator++(void) + { + return *this += one(); + } + cpp_float& operator--(void) + { + return *this -= one(); + } + + std::string str(unsigned digits, bool scientific)const; + + int compare(const cpp_float& v)const; + template + int compare(const V& v)const + { + cpp_float t; + t = v; + return compare(t); + } + + void swap(cpp_float& v) + { + data.swap(v.data); + std::swap(exp, v.exp); + std::swap(neg, v.neg); + std::swap(fpclass, v.fpclass); + std::swap(prec_elem, v.prec_elem); + } + + double extract_double (void) const; + long double extract_long_double (void) const; + signed long long extract_signed_long_long (void) const; + unsigned long long extract_unsigned_long_long(void) const; + void extract_parts (double& mantissa, boost::int64_t& exponent) const; + cpp_float extract_integer_part (void) const; + void precision(const boost::int32_t prec_digits) + { + if(prec_digits >= cpp_float_digits10) + { + prec_elem = mp_elem_number; + } + else + { + const boost::int32_t elems = static_cast( static_cast( (prec_digits + (mp_elem_digits10 / 2)) / mp_elem_digits10) + + static_cast(((prec_digits % mp_elem_digits10) != 0) ? 1 : 0)); + + prec_elem = (std::min)(mp_elem_number, (std::max)(elems, static_cast(2))); + } + } + static cpp_float pow2(long long i); + long long order()const + { + const bool bo_order_is_zero = ((!isfinite()) || (data[0] == static_cast(0u))); + // + // Binary search to find the order of the leading term: + // + boost::uint32_t prefix = 0; + + if(data[0] >= 100000UL) + { + if(data[0] >= 10000000UL) + { + if(data[0] >= 100000000UL) + { + if(data[0] >= 1000000000UL) + prefix = 9; + else + prefix = 8; + } + else + prefix = 7; + } + else + { + if(data[0] >= 1000000UL) + prefix = 6; + else + prefix = 5; + } + } + else + { + if(data[0] >= 1000UL) + { + if(data[0] >= 10000UL) + prefix = 4; + else + prefix = 3; + } + else + { + if(data[0] >= 100) + prefix = 2; + else if(data[0] >= 10) + prefix = 1; + } + } + + return (bo_order_is_zero ? static_cast(0) + : static_cast(exp + prefix)); + } + +private: + static bool data_elem_is_non_zero_predicate(const boost::uint32_t& d) { return (d != static_cast(0u)); } + static bool data_elem_is_non_nine_predicate(const boost::uint32_t& d) { return (d != static_cast(cpp_float::mp_elem_mask - 1)); } + static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast('0')); } + + void from_unsigned_long_long(const unsigned long long u); + + int cmp_data(const array_type& vd) const; + + static void mul_loop_uv(const boost::uint32_t* const u, const boost::uint32_t* const v, boost::uint32_t* const w, const boost::int32_t p); + static boost::uint32_t mul_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p); + static boost::uint32_t div_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p); + + bool rd_string(const char* const s); +}; + +template +typename cpp_float::initializer cpp_float::init; + +template +const boost::int32_t cpp_float::mp_radix; +template +const boost::int32_t cpp_float::cpp_float_digits; +template +const boost::int32_t cpp_float::cpp_float_digits10_setting; +template +const boost::int32_t cpp_float::cpp_float_digits10_limit; +template +const boost::int32_t cpp_float::cpp_float_digits10; +template +const boost::int32_t cpp_float::cpp_float_digits10_extra; +template +const boost::int32_t cpp_float::cpp_float_max_digits10; +template +const boost::int64_t cpp_float::cpp_float_max_exp; +template +const boost::int64_t cpp_float::cpp_float_min_exp; +template +const boost::int64_t cpp_float::cpp_float_max_exp10; +template +const boost::int64_t cpp_float::cpp_float_min_exp10; +template +const boost::int32_t cpp_float::mp_elem_digits10; +template +const boost::int32_t cpp_float::cpp_float_digits10_num_base; +template +const boost::int32_t cpp_float::mp_elem_number; +template +const boost::int32_t cpp_float::mp_elem_mask; + + +template +cpp_float& cpp_float::operator+=(const cpp_float& v) +{ + if(isnan()) + { + return *this; + } + + if(isinf()) + { + if(v.isinf() && (isneg() != v.isneg())) + { + *this = nan(); + } + return *this; + } + + if(iszero()) + { + return operator=(v); + } + + // Get the offset for the add/sub operation. + static const boost::int64_t max_delta_exp = static_cast((mp_elem_number - 1) * mp_elem_digits10); + + const boost::int64_t ofs_exp = static_cast(exp - v.exp); + + // Check if the operation is out of range, requiring special handling. + if(v.iszero() || (ofs_exp > max_delta_exp)) + { + // Result is *this unchanged since v is negligible compared to *this. + return *this; + } + else if(ofs_exp < -max_delta_exp) + { + // Result is *this = v since *this is negligible compared to v. + return operator=(v); + } + + // Do the add/sub operation. + + typename array_type::iterator p_u = data.begin(); + typename array_type::const_iterator p_v = v.data.begin(); + bool b_copy = false; + const boost::int32_t ofs = static_cast(static_cast(ofs_exp) / mp_elem_digits10); + array_type n_data; + + if(neg == v.neg) + { + // Add v to *this, where the data array of either *this or v + // might have to be treated with a positive, negative or zero offset. + // The result is stored in *this. The data are added one element + // at a time, each element with carry. + if(ofs >= static_cast(0)) + { + std::copy(v.data.begin(), v.data.end() - static_cast(ofs), n_data.begin() + static_cast(ofs)); + std::fill(n_data.begin(), n_data.begin() + static_cast(ofs), static_cast(0u)); + p_v = n_data.begin(); + } + else + { + std::copy(data.begin(), data.end() - static_cast(-ofs), n_data.begin() + static_cast(-ofs)); + std::fill(n_data.begin(), n_data.begin() + static_cast(-ofs), static_cast(0u)); + p_u = n_data.begin(); + b_copy = true; + } + + // Addition algorithm + boost::uint32_t carry = static_cast(0u); + + for(boost::int32_t j = static_cast(mp_elem_number - static_cast(1)); j >= static_cast(0); j--) + { + boost::uint32_t t = static_cast(static_cast(p_u[j] + p_v[j]) + carry); + carry = t / static_cast(mp_elem_mask); + p_u[j] = static_cast(t - static_cast(carry * static_cast(mp_elem_mask))); + } + + if(b_copy) + { + data = n_data; + exp = v.exp; + } + + // There needs to be a carry into the element -1 of the array data + if(carry != static_cast(0u)) + { + std::copy_backward(data.begin(), data.end() - static_cast(1u), data.end()); + data[0] = carry; + exp += static_cast(mp_elem_digits10); + } + } + else + { + // Subtract v from *this, where the data array of either *this or v + // might have to be treated with a positive, negative or zero offset. + if((ofs > static_cast(0)) + || ( (ofs == static_cast(0)) + && (cmp_data(v.data) > static_cast(0))) + ) + { + // In this case, |u| > |v| and ofs is positive. + // Copy the data of v, shifted down to a lower value + // into the data array m_n. Set the operand pointer p_v + // to point to the copied, shifted data m_n. + std::copy(v.data.begin(), v.data.end() - static_cast(ofs), n_data.begin() + static_cast(ofs)); + std::fill(n_data.begin(), n_data.begin() + static_cast(ofs), static_cast(0u)); + p_v = n_data.begin(); + } + else + { + if(ofs != static_cast(0)) + { + // In this case, |u| < |v| and ofs is negative. + // Shift the data of u down to a lower value. + std::copy_backward(data.begin(), data.end() - static_cast(-ofs), data.end()); + std::fill(data.begin(), data.begin() + static_cast(-ofs), static_cast(0u)); + } + + // Copy the data of v into the data array n_data. + // Set the u-pointer p_u to point to m_n and the + // operand pointer p_v to point to the shifted + // data m_data. + n_data = v.data; + p_u = n_data.begin(); + p_v = data.begin(); + b_copy = true; + } + + boost::int32_t j; + + // Subtraction algorithm + boost::int32_t borrow = static_cast(0); + + for(j = static_cast(mp_elem_number - static_cast(1)); j >= static_cast(0); j--) + { + boost::int32_t t = static_cast(static_cast( static_cast(p_u[j]) + - static_cast(p_v[j])) - borrow); + + // Underflow? Borrow? + if(t < static_cast(0)) + { + // Yes, underflow and borrow + t += static_cast(mp_elem_mask); + borrow = static_cast(1); + } + else + { + borrow = static_cast(0); + } + + p_u[j] = static_cast(static_cast(t) % static_cast(mp_elem_mask)); + } + + if(b_copy) + { + data = n_data; + exp = v.exp; + neg = v.neg; + } + + // Is it necessary to justify the data? + const typename array_type::const_iterator first_nonzero_elem = std::find_if(data.begin(), data.end(), data_elem_is_non_zero_predicate); + + if(first_nonzero_elem != data.begin()) + { + if(first_nonzero_elem == data.end()) + { + // This result of the subtraction is exactly zero. + // Reset the sign and the exponent. + neg = false; + exp = static_cast(0); + } + else + { + // Justify the data + const std::size_t sj = static_cast(std::distance(data.begin(), first_nonzero_elem)); + + std::copy(data.begin() + static_cast(sj), data.end(), data.begin()); + std::fill(data.end() - sj, data.end(), static_cast(0u)); + + exp -= static_cast(sj * static_cast(mp_elem_digits10)); + } + } + } + + // Check for underflow. + if(iszero()) + { + return *this = zero(); + } + + bool overflow = exp >= cpp_float_max_exp; + if(exp == cpp_float_max_exp) + { + // Check to see if we really truely have an overflow or not... + if(isneg()) + { + cpp_float t(*this); + t.negate(); + overflow = t.compare((max)()) > 0; + } + else + { + overflow = compare((max)()) > 0; + } + } + + // Check for overflow. + if(overflow) + { + const bool b_result_is_neg = neg; + + *this = inf(); + if(b_result_is_neg) + negate(); + } + + return *this; +} + +template +cpp_float& cpp_float::operator-=(const cpp_float& v) +{ + // Use *this - v = -(-*this + v). + negate(); + *this += v; + negate(); + return *this; +} + +template +cpp_float& cpp_float::operator*=(const cpp_float& v) +{ + // Evaluate the sign of the result. + const bool b_result_is_neg = (neg != v.neg); + + // Artificially set the sign of the result to be positive. + neg = false; + + // Handle special cases like zero, inf and NaN. + const bool b_u_is_inf = isinf(); + const bool b_v_is_inf = v.isinf(); + const bool b_u_is_zero = iszero(); + const bool b_v_is_zero = v.iszero(); + + if( (isnan() || v.isnan()) + || (b_u_is_inf && b_v_is_zero) + || (b_v_is_inf && b_u_is_zero) + ) + { + *this = nan(); + return *this; + } + + if(b_u_is_inf || b_v_is_inf) + { + *this = inf(); + if(b_result_is_neg) + negate(); + return *this; + } + + if(b_u_is_zero || b_v_is_zero) + { + return *this = zero(); + } + + // Check for overflow or underflow. + const bool u_exp_is_neg = (exp < static_cast(0)); + const bool v_exp_is_neg = (v.exp < static_cast(0)); + + if(u_exp_is_neg == v_exp_is_neg) + { + // Get the unsigned base-10 exponents of *this and v and... + const boost::int64_t u_exp = ((!u_exp_is_neg) ? exp : static_cast( -exp)); + const boost::int64_t v_exp = ((!v_exp_is_neg) ? v.exp : static_cast(-v.exp)); + + // Check the range of the upcoming multiplication. + const bool b_result_is_out_of_range = (v_exp >= static_cast(cpp_float_max_exp10 - u_exp)); + + if(b_result_is_out_of_range) + { + if(u_exp_is_neg) + { + *this = zero(); + } + else + { + *this = inf(); + if(b_result_is_neg) + negate(); + } + return *this; + } + } + + // Set the exponent of the result. + exp += v.exp; + + boost::array(mp_elem_number + static_cast(1))> w = {{ 0u }}; + + mul_loop_uv(data.data(), v.data.data(), w.data(), (std::min)(prec_elem, v.prec_elem)); + + // Copy the multiplication data into the result. + // Shift the result and adjust the exponent if necessary. + if(w[static_cast(0u)] != static_cast(0u)) + { + exp += static_cast(mp_elem_digits10); + + std::copy(w.begin(), w.end() - 1u, data.begin()); + } + else + { + std::copy(w.begin() + 1u, w.end(), data.begin()); + } + + // Set the sign of the result. + neg = b_result_is_neg; + + return *this; +} + +template +cpp_float& cpp_float::operator/=(const cpp_float& v) +{ + const bool u_and_v_are_finite_and_identical = ( isfinite() + && (fpclass == v.fpclass) + && (exp == v.exp) + && (cmp_data(v.data) == static_cast(0))); + + if(u_and_v_are_finite_and_identical) + { + *this = one(); + if(neg != v.neg) + negate(); + return *this; + } + else + { + if(iszero()) + { + if(v.isnan() || v.iszero()) + { + return *this = v; + } + return *this; + } + cpp_float t(v); + t.calculate_inv(); + return operator*=(t); + } +} + +template +cpp_float& cpp_float::mul_unsigned_long_long(const unsigned long long n) +{ + // Multiply *this with a constant unsigned long long. + + // Evaluate the sign of the result. + const bool b_neg = neg; + + // Artificially set the sign of the result to be positive. + neg = false; + + // Handle special cases like zero, inf and NaN. + const bool b_u_is_inf = isinf(); + const bool b_n_is_zero = (n == static_cast(0)); + + if(isnan() || (b_u_is_inf && b_n_is_zero)) + { + return (*this = nan()); + } + + if(b_u_is_inf) + { + *this = inf(); + if(b_neg) + negate(); + return *this; + } + + if(iszero() || b_n_is_zero) + { + // Multiplication by zero. + return *this = zero(); + } + + if(n >= static_cast(mp_elem_mask)) + { + neg = b_neg; + cpp_float t; + t = n; + return operator*=(t); + } + + if(n == static_cast(1u)) + { + neg = b_neg; + return *this; + } + + // Set up the multiplication loop. + const boost::uint32_t nn = static_cast(n); + const boost::uint32_t carry = mul_loop_n(data.data(), nn, prec_elem); + + // Handle the carry and adjust the exponent. + if(carry != static_cast(0u)) + { + exp += static_cast(mp_elem_digits10); + + // Shift the result of the multiplication one element to the right. + std::copy_backward(data.begin(), + data.begin() + static_cast(prec_elem - static_cast(1)), + data.begin() + static_cast(prec_elem)); + + data.front() = static_cast(carry); + } + + bool overflow = exp >= cpp_float_max_exp; + if(exp == cpp_float_max_exp) + { + // Check to see if we really truely have an overflow or not... + if(isneg()) + { + cpp_float t(*this); + t.negate(); + overflow = t.compare((max)()) > 0; + } + else + { + overflow = compare((max)()) > 0; + } + } + + if(overflow) + { + *this = inf(); + if(b_neg) + negate(); + return *this; + } + + // Set the sign. + neg = b_neg; + + return *this; +} + +template +cpp_float& cpp_float::div_unsigned_long_long(const unsigned long long n) +{ + // Divide *this by a constant unsigned long long. + + // Evaluate the sign of the result. + const bool b_neg = neg; + + // Artificially set the sign of the result to be positive. + neg = false; + + // Handle special cases like zero, inf and NaN. + if(isnan()) + { + return *this; + } + + if(isinf()) + { + *this = inf(); + if(b_neg) + negate(); + return *this; + } + + if(n == static_cast(0u)) + { + // Divide by 0. + if(iszero()) + { + *this = nan(); + return *this; + } + else + { + *this = inf(); + if(isneg()) + negate(); + return *this; + } + } + + if(iszero()) + { + return *this; + } + + if(n >= static_cast(mp_elem_mask)) + { + neg = b_neg; + cpp_float t; + t = n; + return operator/=(t); + } + + const boost::uint32_t nn = static_cast(n); + + if(nn > static_cast(1u)) + { + // Do the division loop. + const boost::uint32_t prev = div_loop_n(data.data(), nn, prec_elem); + + // Determine if one leading zero is in the result data. + if(data[0] == static_cast(0u)) + { + // Adjust the exponent + exp -= static_cast(mp_elem_digits10); + + // Shift result of the division one element to the left. + std::copy(data.begin() + static_cast(1u), + data.begin() + static_cast(prec_elem - static_cast(1)), + data.begin()); + + data[prec_elem - static_cast(1)] = static_cast(static_cast(prev * static_cast(mp_elem_mask)) / nn); + } + } + + // Check for underflow. + if(iszero()) + { + return *this = zero(); + } + + // Set the sign of the result. + neg = b_neg; + + return *this; +} + +template +cpp_float& cpp_float::calculate_inv() +{ + // Compute the inverse of *this. + const bool b_neg = neg; + + neg = false; + + // Handle special cases like zero, inf and NaN. + if(iszero()) + { + *this = inf(); + if(b_neg) + negate(); + return *this; + } + + if(isnan()) + { + return *this; + } + + if(isinf()) + { + return *this = zero(); + } + + if(isone()) + { + if(b_neg) + negate(); + return *this; + } + + // Save the original *this. + cpp_float x(*this); + + // Generate the initial estimate using division. + // Extract the mantissa and exponent for a "manual" + // computation of the estimate. + double dd; + boost::int64_t ne; + x.extract_parts(dd, ne); + + // Do the inverse estimate using double precision estimates of mantissa and exponent. + operator=(cpp_float(1.0 / dd, -ne)); + + // Compute the inverse of *this. Quadratically convergent Newton-Raphson iteration + // is used. During the iterative steps, the precision of the calculation is limited + // to the minimum required in order to minimize the run-time. + + static const boost::int32_t double_digits10_minus_one = std::numeric_limits::digits10 - 1; + + for(boost::uint32_t digits = double_digits10_minus_one; digits <= Digits10; digits *= static_cast(2)) + { + // Adjust precision of the terms. + precision(static_cast(digits * static_cast(2))); + x.precision(static_cast(digits * static_cast(2))); + + // Next iteration. + cpp_float t(*this); + t *= x; + t -= two(); + t.negate(); + *this *= t; + } + + neg = b_neg; + + prec_elem = mp_elem_number; + + return *this; +} + +template +cpp_float& cpp_float::calculate_sqrt(void) +{ + // Compute the square root of *this. + + if(isneg() || (!isfinite())) + { + *this = nan(); + return *this; + } + + if(iszero() || isone()) + { + return *this; + } + + // Save the original *this. + cpp_float x(*this); + + // Generate the initial estimate using division. + // Extract the mantissa and exponent for a "manual" + // computation of the estimate. + double dd; + boost::int64_t ne; + extract_parts(dd, ne); + + // Force the exponent to be an even multiple of two. + if((ne % static_cast(2)) != static_cast(0)) + { + ++ne; + dd /= 10.0; + } + + // Setup the iteration. + // Estimate the square root using simple manipulations. + const double sqd = std::sqrt(dd); + + *this = cpp_float(sqd, static_cast(ne / static_cast(2))); + + // Estimate 1.0 / (2.0 * x0) using simple manipulations. + cpp_float vi(0.5 / sqd, static_cast(-ne / static_cast(2))); + + // Compute the square root of x. Coupled Newton iteration + // as described in "Pi Unleashed" is used. During the + // iterative steps, the precision of the calculation is + // limited to the minimum required in order to minimize + // the run-time. + // + // Book references: + // http://www.jjj.de/pibook/pibook.html + // http://www.amazon.com/exec/obidos/tg/detail/-/3540665722/qid=1035535482/sr=8-7/ref=sr_8_7/104-3357872-6059916?v=glance&n=507846 + + static const boost::uint32_t double_digits10_minus_one = static_cast(static_cast(Digits10) - static_cast(1)); + + for(boost::uint32_t digits = double_digits10_minus_one; digits <= Digits10; digits *= 2u) + { + // Adjust precision of the terms. + precision(digits * 2); + vi.precision(digits * 2); + + // Next iteration of vi + cpp_float t(*this); + t *= vi; + t.negate(); + t.mul_unsigned_long_long(2u); + t += one(); + t *= vi; + vi += t; + + // Next iteration of *this + t = *this; + t *= *this; + t.negate(); + t += x; + t *= vi; + *this += t; + } + + prec_elem = mp_elem_number; + + return *this; +} + +template +int cpp_float::cmp_data(const array_type& vd) const +{ + // Compare the data of *this with those of v. + // Return +1 for *this > v + // 0 for *this = v + // -1 for *this < v + + const std::pair mismatch_pair = std::mismatch(data.begin(), data.end(), vd.begin()); + + const bool is_equal = ((mismatch_pair.first == data.end()) && (mismatch_pair.second == vd.end())); + + if(is_equal) + { + return 0; + } + else + { + return ((*mismatch_pair.first > *mismatch_pair.second) ? 1 : -1); + } +} + +template +int cpp_float::compare(const cpp_float& v) const +{ + // Compare v with *this. + // Return +1 for *this > v + // 0 for *this = v + // -1 for *this < v + + // Handle all non-finite cases. + if((!isfinite()) || (!v.isfinite())) + { + // NaN can never equal NaN. Return an implementation-dependent + // signed result. Also note that comparison of NaN with NaN + // using operators greater-than or less-than is undefined. + if(isnan() || v.isnan()) { return (isnan() ? 1 : -1); } + + if(isinf() && v.isinf()) + { + // Both *this and v are infinite. They are equal if they have the same sign. + // Otherwise, *this is less than v if and only if *this is negative. + return ((neg == v.neg) ? 0 : (neg ? -1 : 1)); + } + + if(isinf()) + { + // *this is infinite, but v is finite. + // So negative infinite *this is less than any finite v. + // Whereas positive infinite *this is greater than any finite v. + return (isneg() ? -1 : 1); + } + else + { + // *this is finite, and v is infinite. + // So any finite *this is greater than negative infinite v. + // Whereas any finite *this is less than positive infinite v. + return (v.neg ? 1 : -1); + } + } + + // And now handle all *finite* cases. + if(iszero()) + { + // The value of *this is zero and v is either zero or non-zero. + return (v.iszero() ? 0 + : (v.neg ? 1 : -1)); + } + else if(v.iszero()) + { + // The value of v is zero and *this is non-zero. + return (neg ? -1 : 1); + } + else + { + // Both *this and v are non-zero. + + if(neg != v.neg) + { + // The signs are different. + return (neg ? -1 : 1); + } + else if(exp != v.exp) + { + // The signs are the same and the exponents are different. + const int val_cmp_exp = ((exp < v.exp) ? 1 : -1); + + return (neg ? val_cmp_exp : -val_cmp_exp); + } + else + { + // The signs are the same and the exponents are the same. + // Compare the data. + const int val_cmp_data = cmp_data(v.data); + + return ((!neg) ? val_cmp_data : -val_cmp_data); + } + } +} + +template +bool cpp_float::isone() const +{ + // Check if the value of *this is identically 1 or very close to 1. + + const bool not_negative_and_is_finite = ((!neg) && isfinite()); + + if(not_negative_and_is_finite) + { + if((data[0u] == static_cast(1u)) && (exp == static_cast(0))) + { + const typename array_type::const_iterator it_non_zero = std::find_if(data.begin(), data.end(), data_elem_is_non_zero_predicate); + return (it_non_zero == data.end()); + } + else if((data[0u] == static_cast(mp_elem_mask - 1)) && (exp == static_cast(-mp_elem_digits10))) + { + const typename array_type::const_iterator it_non_nine = std::find_if(data.begin(), data.end(), data_elem_is_non_nine_predicate); + return (it_non_nine == data.end()); + } + } + + return false; +} + +template +bool cpp_float::isint() const +{ + if(fpclass != mp_finite) { return false; } + + if(iszero()) { return true; } + + if(exp < static_cast(0)) { return false; } // |*this| < 1. + + const typename array_type::size_type offset_decimal_part = static_cast(exp / mp_elem_digits10) + 1u; + + if(offset_decimal_part >= static_cast(mp_elem_number)) + { + // The number is too large to resolve the integer part. + // It considered to be a pure integer. + return true; + } + + typename array_type::const_iterator it_non_zero = std::find_if(data.begin() + offset_decimal_part, data.end(), data_elem_is_non_zero_predicate); + + return (it_non_zero == data.end()); +} + +template +void cpp_float::extract_parts(double& mantissa, boost::int64_t& exponent) const +{ + // Extract the approximate parts mantissa and base-10 exponent from the input cpp_float value x. + + // Extracts the mantissa and exponent. + exponent = exp; + + boost::uint32_t p10 = static_cast(1u); + boost::uint32_t test = data[0u]; + + for(;;) + { + test /= static_cast(10u); + + if(test == static_cast(0u)) + { + break; + } + + p10 *= static_cast(10u); + ++exponent; + } + + mantissa = static_cast(data[0]) + + (static_cast(data[1]) / static_cast(mp_elem_mask)) + + ((static_cast(data[2]) / static_cast(mp_elem_mask)) / static_cast(mp_elem_mask)); + + mantissa /= static_cast(p10); + + if(neg) { mantissa = -mantissa; } +} + +template +double cpp_float::extract_double(void) const +{ + // Returns the double conversion of a cpp_float. + + // Check for non-normal cpp_float. + if(!isfinite()) + { + if(isnan()) + { + return std::numeric_limits::quiet_NaN(); + } + else + { + return ((!neg) ? std::numeric_limits::infinity() + : -std::numeric_limits::infinity()); + } + } + + cpp_float xx(*this); + if(xx.isneg()) + xx.negate(); + + // Check for zero cpp_float. + if(iszero() || (xx.compare(double_min()) < 0)) + { + return 0.0; + } + + // Check if cpp_float exceeds the maximum of double. + if(xx.compare(double_max()) > 0) + { + return ((!neg) ? std::numeric_limits::infinity() + : -std::numeric_limits::infinity()); + } + + std::stringstream ss; + + ss << str(std::numeric_limits::digits10 + (2 + 1), true); + + double d; + ss >> d; + + return d; +} + +template +long double cpp_float::extract_long_double(void) const +{ + // Returns the long double conversion of a cpp_float. + + // Check for non-normal cpp_float. + if(!isfinite()) + { + if(isnan()) + { + return std::numeric_limits::quiet_NaN(); + } + else + { + return ((!neg) ? std::numeric_limits::infinity() + : -std::numeric_limits::infinity()); + } + } + + cpp_float xx(*this); + if(xx.isneg()) + xx.negate(); + + // Check for zero cpp_float. + if(iszero() || (xx.compare(long_double_min()) < 0)) + { + return static_cast(0.0); + } + + // Check if cpp_float exceeds the maximum of double. + if(xx.compare(long_double_max()) > 0) + { + return ((!neg) ? std::numeric_limits::infinity() + : -std::numeric_limits::infinity()); + } + + std::stringstream ss; + + ss << str(std::numeric_limits::digits10 + (2 + 1), true); + + long double ld; + ss >> ld; + + return ld; +} + +template +signed long long cpp_float::extract_signed_long_long(void) const +{ + // Extracts a signed long long from *this. + // If (x > maximum of signed long long) or (x < minimum of signed long long), + // then the maximum or minimum of signed long long is returned accordingly. + + if(exp < static_cast(0)) + { + return static_cast(0); + } + + const bool b_neg = isneg(); + + unsigned long long val; + + if((!b_neg) && (compare(long_long_max()) > 0)) + { + return (std::numeric_limits::max)(); + } + else if(b_neg && (compare(long_long_min()) < 0)) + { + return (std::numeric_limits::min)(); + } + else + { + // Extract the data into an unsigned long long value. + cpp_float xn(extract_integer_part()); + if(xn.isneg()) + xn.negate(); + + val = static_cast(xn.data[0]); + + const boost::int32_t imax = (std::min)(static_cast(static_cast(xn.exp) / mp_elem_digits10), static_cast(mp_elem_number - static_cast(1))); + + for(boost::int32_t i = static_cast(1); i <= imax; i++) + { + val *= static_cast(mp_elem_mask); + val += static_cast(xn.data[i]); + } + } + + return ((!b_neg) ? static_cast(val) : static_cast(-static_cast(val))); +} + +template +unsigned long long cpp_float::extract_unsigned_long_long(void) const +{ + // Extracts an unsigned long long from *this. + // If x exceeds the maximum of unsigned long long, + // then the maximum of unsigned long long is returned. + // If x is negative, then the unsigned long long cast of + // the signed long long extracted value is returned. + + if(isneg()) + { + return static_cast(extract_signed_long_long()); + } + + if(exp < static_cast(0)) + { + return static_cast(0u); + } + + const cpp_float xn(extract_integer_part()); + + unsigned long long val; + + if(xn.compare(ulong_long_max()) > 0) + { + return (std::numeric_limits::max)(); + } + else + { + // Extract the data into an unsigned long long value. + val = static_cast(xn.data[0]); + + const boost::int32_t imax = (std::min)(static_cast(static_cast(xn.exp) / mp_elem_digits10), static_cast(mp_elem_number - static_cast(1))); + + for(boost::int32_t i = static_cast(1); i <= imax; i++) + { + val *= static_cast(mp_elem_mask); + val += static_cast(xn.data[i]); + } + } + + return val; +} + +template +cpp_float cpp_float::extract_integer_part(void) const +{ + // Compute the signed integer part of x. + + if(!isfinite()) + { + return *this; + } + + if(exp < static_cast(0)) + { + // The absolute value of the number is smaller than 1. + // Thus the integer part is zero. + return zero(); + } + else if(exp >= Digits10 - 1) + { + // The number is too large to resolve the integer part. + // Thus it is already a pure integer part. + return *this; + } + + // Make a local copy. + cpp_float x = *this; + + // Clear out the decimal portion + const size_t first_clear = (static_cast(x.exp) / static_cast(mp_elem_digits10)) + 1u; + const size_t last_clear = static_cast(mp_elem_number); + + std::fill(x.data.begin() + first_clear, x.data.begin() + last_clear, static_cast(0u)); + + return x; +} + +template +std::string cpp_float::str(std::size_t number_of_digits, bool scientific) const +{ + std::string str; + boost::int64_t my_exp = order(); + if(number_of_digits == 0) + number_of_digits = (std::numeric_limits::max)(); + // Determine the number of elements needed to provide the requested digits from cpp_float. + const std::size_t number_of_elements = (std::min)(static_cast((number_of_digits / static_cast(mp_elem_digits10)) + 2u), + static_cast(mp_elem_number)); + + // Extract the remaining digits from cpp_float after the decimal point. + str = boost::lexical_cast(data[0]); + + // Extract all of the digits from cpp_float, beginning with the first data element. + for(std::size_t i = static_cast(1u); i < number_of_elements; i++) + { + std::stringstream ss; + + ss << std::setw(static_cast(mp_elem_digits10)) + << std::setfill(static_cast('0')) + << data[i]; + + str += ss.str(); + } + + // Cut the output to the size of the precision. + if(str.length() > number_of_digits) + { + // Get the digit after the last needed digit for rounding + const boost::uint32_t round = static_cast(static_cast(str.at(number_of_digits)) - static_cast('0')); + + // Truncate the string + str = str.substr(static_cast(0u), number_of_digits); + + if(round >= static_cast(5u)) + { + std::size_t ix = static_cast(str.length() - 1u); + + // Every trailing 9 must be rounded up + while(ix && (static_cast(str.at(ix)) - static_cast('0') == static_cast(9))) + { + str.at(ix) = static_cast('0'); + --ix; + } + + if(!ix) + { + // There were nothing but trailing nines. + if(static_cast(static_cast(str.at(ix)) - static_cast(0x30)) == static_cast(9)) + { + // Increment up to the next order and adjust exponent. + str.at(ix) = static_cast('1'); + ++my_exp; + } + else + { + // Round up this digit. + ++str.at(ix); + } + } + else + { + // Round up the last digit. + ++str[ix]; + } + } + } + // + // Suppress trailing zeros: + // + std::string::iterator pos = str.end(); + while(pos != str.begin() && *--pos == '0'){} + if(pos != str.end()) + ++pos; + str.erase(pos, str.end()); + if(str.empty()) + str = '0'; + if(!scientific && (str.size() < 20) && (my_exp >= 0) && (my_exp < 20)) + { + if(1 + my_exp > str.size()) + { + // Just pad out the end with zeros: + str.append(static_cast(1 + my_exp - str.size()), '0'); + } + else if(my_exp + 1 != str.size()) + { + // Insert the decimal point: + str.insert(static_cast(my_exp + 1), 1, '.'); + } + } + else + { + // Scientific format: + str.insert(1, 1, '.'); + if(str.size() == 2) + str.append(1, '0'); + str.append(1, 'e'); + str.append(boost::lexical_cast(my_exp)); + } + if(isneg()) + str.insert(0, 1, '-'); + return str; +} + +template +bool cpp_float::rd_string(const char* const s) +{ + std::string str(s); + + // Get a possible exponent and remove it. + exp = static_cast(0); + + std::size_t pos; + + if( ((pos = str.find('e')) != std::string::npos) + || ((pos = str.find('E')) != std::string::npos) + ) + { + // Remove the exponent part from the string. + exp = boost::lexical_cast(static_cast(str.c_str() + (pos + 1u))); + str = str.substr(static_cast(0u), pos); + } + + // Get a possible +/- sign and remove it. + neg = false; + + if((pos = str.find(static_cast('-'))) != std::string::npos) + { + neg = true; + str.erase(pos, static_cast(1u)); + } + + if((pos = str.find(static_cast('+'))) != std::string::npos) + { + str.erase(pos, static_cast(1u)); + } + + // Remove leading zeros for all input types. + const std::string::iterator fwd_it_leading_zero = std::find_if(str.begin(), str.end(), char_is_nonzero_predicate); + + if(fwd_it_leading_zero != str.begin()) + { + if(fwd_it_leading_zero == str.end()) + { + // The string contains nothing but leading zeros. + // This string represents zero. + operator=(zero()); + return true; + } + else + { + str.erase(str.begin(), fwd_it_leading_zero); + } + } + + // Put the input string into the standard cpp_float input form + // aaa.bbbbE+/-n, where aa has 1...mp_elem_digits10, bbbb has an + // even multiple of mp_elem_digits10 which are possibly zero padded + // on the right-end, and n is a signed 32-bit integer which is an + // even multiple of mp_elem_digits10. + + // Find a possible decimal point. + pos = str.find(static_cast('.')); + + if(pos != std::string::npos) + { + // Remove all trailing insignificant zeros. + const std::string::const_reverse_iterator rit_non_zero = std::find_if(str.rbegin(), str.rend(), char_is_nonzero_predicate); + + if(rit_non_zero != str.rbegin()) + { + const std::string::size_type ofs = str.length() - std::distance(str.rbegin(), rit_non_zero); + str.erase(str.begin() + ofs, str.end()); + } + + // Check if the input is identically zero. + if(str == std::string(".")) + { + operator=(zero()); + return true; + } + + // Remove leading significant zeros just after the decimal point + // and adjust the exponent accordingly. + // Note that the while-loop operates only on strings of the form ".000abcd..." + // and peels away the zeros just after the decimal point. + if(str.at(static_cast(0u)) == static_cast('.')) + { + const std::string::iterator it_non_zero = std::find_if(str.begin() + 1u, str.end(), char_is_nonzero_predicate); + + std::size_t delta_exp = static_cast(0u); + + if(str.at(static_cast(1u)) == static_cast('0')) + { + delta_exp = std::distance(str.begin() + 1u, it_non_zero); + } + + // Bring one single digit into the mantissa and adjust exponent accordingly. + str.erase(str.begin(), it_non_zero); + str.insert(static_cast(1u), "."); + exp -= static_cast(delta_exp + 1u); + } + } + else + { + // Input string has no decimal point: Append decimal point. + str.append("."); + } + + // Shift the decimal point such that the exponent is an even multiple of mp_elem_digits10. + std::size_t n_shift = static_cast(0u); + const std::size_t n_exp_rem = static_cast(exp % static_cast(mp_elem_digits10)); + + if((exp % static_cast(mp_elem_digits10)) != static_cast(0)) + { + n_shift = ((exp < static_cast(0)) + ? static_cast(n_exp_rem + static_cast(mp_elem_digits10)) + : static_cast(n_exp_rem)); + } + + // Make sure that there are enough digits for the decimal point shift. + pos = str.find(static_cast('.')); + + std::size_t pos_plus_one = static_cast(pos + 1u); + + if((str.length() - pos_plus_one) < n_shift) + { + const std::size_t sz = static_cast(n_shift - (str.length() - pos_plus_one)); + + str.append(std::string(sz, static_cast('0'))); + } + + // Do the decimal point shift. + if(n_shift != static_cast(0u)) + { + str.insert(static_cast(pos_plus_one + n_shift), "."); + + str.erase(pos, static_cast(1u)); + + exp -= static_cast(n_shift); + } + + // Cut the size of the mantissa to <= mp_elem_digits10. + pos = str.find(static_cast('.')); + pos_plus_one = static_cast(pos + 1u); + + if(pos > static_cast(mp_elem_digits10)) + { + const boost::int32_t n_pos = static_cast(pos); + const boost::int32_t n_rem_is_zero = ((static_cast(n_pos % mp_elem_digits10) == static_cast(0)) ? static_cast(1) : static_cast(0)); + const boost::int32_t n = static_cast(static_cast(n_pos / mp_elem_digits10) - n_rem_is_zero); + + str.insert(static_cast(static_cast(n_pos - static_cast(n * mp_elem_digits10))), "."); + + str.erase(pos_plus_one, static_cast(1u)); + + exp += static_cast(static_cast(n) * static_cast(mp_elem_digits10)); + } + + // Pad the decimal part such that its value is an even + // multiple of mp_elem_digits10. + pos = str.find(static_cast('.')); + pos_plus_one = static_cast(pos + 1u); + + const boost::int32_t n_dec = static_cast(static_cast(str.length() - 1u) - static_cast(pos)); + const boost::int32_t n_rem = static_cast(n_dec % mp_elem_digits10); + boost::int32_t n_cnt = ((n_rem != static_cast(0)) ? static_cast(mp_elem_digits10 - n_rem) + : static_cast(0)); + + if(n_cnt != static_cast(0)) + { + str.append(static_cast(n_cnt), static_cast('0')); + } + + // Truncate decimal part if it is too long. + const std::size_t max_dec = static_cast((mp_elem_number - 1) * mp_elem_digits10); + + if(static_cast(str.length() - pos) > max_dec) + { + str = str.substr(static_cast(0u), + static_cast(pos_plus_one + max_dec)); + } + + // Now the input string has the standard cpp_float input form. + // (See the comment above.) + + // Set all the data elements to 0. + std::fill(data.begin(), data.end(), static_cast(0u)); + + // Extract the data. + + // First get the digits to the left of the decimal point... + data[0u] = boost::lexical_cast(str.substr(static_cast(0u), pos)); + + // ...then get the remaining digits to the right of the decimal point. + const std::string::size_type i_end = ((str.length() - pos_plus_one) / static_cast(mp_elem_digits10)); + + for(std::string::size_type i = static_cast(0u); i < i_end; i++) + { + const std::string::const_iterator it = str.begin() + + pos_plus_one + + (i * static_cast(mp_elem_digits10)); + + data[i + 1u] = boost::lexical_cast(std::string(it, it + static_cast(mp_elem_digits10))); + } + + // Check for overflow... + if(exp > cpp_float_max_exp10) + { + const bool b_result_is_neg = neg; + + *this = inf(); + if(b_result_is_neg) + negate(); + } + + // ...and check for underflow. + if(exp <= cpp_float_min_exp10) + { + if(exp == cpp_float_min_exp10) + { + // Check for identity with the minimum value. + cpp_float test = *this; + + test.exp = static_cast(0); + + if(test.isone()) + { + *this = zero(); + } + } + else + { + *this = zero(); + } + } + + return true; +} + +template +cpp_float::cpp_float(const double mantissa, const boost::int64_t exponent) + : data (), + exp (static_cast(0)), + neg (false), + fpclass (mp_finite), + prec_elem(mp_elem_number) +{ + // Create an cpp_float from mantissa and exponent. + // This ctor does not maintain the full precision of double. + + const bool mantissa_is_iszero = (::fabs(mantissa) < ((std::numeric_limits::min)() * (1.0 + std::numeric_limits::epsilon()))); + + if(mantissa_is_iszero) + { + std::fill(data.begin(), data.end(), static_cast(0u)); + return; + } + + const bool b_neg = (mantissa < 0.0); + + double d = ((!b_neg) ? mantissa : -mantissa); + boost::int64_t e = exponent; + + while(d > 10.0) { d /= 10.0; ++e; } + while(d < 1.0) { d *= 10.0; --e; } + + boost::int32_t shift = static_cast(e % static_cast(mp_elem_digits10)); + + while(static_cast(shift-- % mp_elem_digits10) != static_cast(0)) + { + d *= 10.0; + --e; + } + + exp = e; + neg = b_neg; + + std::fill(data.begin(), data.end(), static_cast(0u)); + + static const boost::int32_t digit_ratio = static_cast(static_cast(std::numeric_limits::digits10) / static_cast(mp_elem_digits10)); + static const boost::int32_t digit_loops = static_cast(digit_ratio + static_cast(2)); + + for(boost::int32_t i = static_cast(0); i < digit_loops; i++) + { + boost::uint32_t n = static_cast(static_cast(d)); + data[i] = static_cast(n); + d -= static_cast(n); + d *= static_cast(mp_elem_mask); + } +} + +template +cpp_float& cpp_float::operator = (long double a) +{ + // Christopher Kormanyos's original code used a cast to long long here, but that fails + // when long double has more digits than a long long. + using std::frexp; + using std::ldexp; + using std::floor; + + if (a == 0) { + return *this = zero(); + } + + if (a == 1) { + return *this = one(); + } + + if((boost::math::isinf)(a)) + { + return *this = inf(); + } + if((boost::math::isnan)(a)) + return *this = nan(); + + int e; + long double f, term; + *this = zero(); + + f = frexp(a, &e); + + static const int shift = std::numeric_limits::digits - 1; + + while(f) + { + // extract int sized bits from f: + f = ldexp(f, shift); + term = floor(f); + e -= shift; + *this *= pow2(shift); + if(term > 0) + add_unsigned_long_long(static_cast(term)); + else + sub_unsigned_long_long(static_cast(-term)); + f -= term; + } + if(e != 0) + *this *= pow2(e); + return *this; +} + +template +void cpp_float::from_unsigned_long_long(const unsigned long long u) +{ + std::fill(data.begin(), data.end(), static_cast(0u)); + + exp = static_cast(0); + neg = false; + fpclass = mp_finite; + prec_elem = mp_elem_number; + + std::size_t i =static_cast(0u); + + unsigned long long uu = u; + + boost::uint32_t temp[(std::numeric_limits::digits10 / static_cast(mp_elem_digits10)) + 3] = { static_cast(0u) }; + + while(uu != static_cast(0u)) + { + temp[i] = static_cast(uu % static_cast(mp_elem_mask)); + uu = static_cast(uu / static_cast(mp_elem_mask)); + ++i; + } + + if(i > static_cast(1u)) + { + exp += static_cast((i - 1u) * static_cast(mp_elem_digits10)); + } + + std::reverse(temp, temp + i); + std::copy(temp, temp + (std::min)(i, static_cast(mp_elem_number)), data.begin()); +} + +template +void cpp_float::mul_loop_uv(const boost::uint32_t* const u, const boost::uint32_t* const v, boost::uint32_t* const w, const boost::int32_t p) +{ + boost::uint64_t carry = static_cast(0u); + + for(boost::int32_t j = static_cast(p - 1u); j >= static_cast(0); j--) + { + boost::uint64_t sum = carry; + + for(boost::int32_t i = j; i >= static_cast(0); i--) + { + sum += static_cast(u[i] * static_cast(v[j - i])); + } + + w[j + 1] = static_cast(sum % static_cast(mp_elem_mask)); + carry = static_cast(sum / static_cast(mp_elem_mask)); + } + + w[0u] = static_cast(carry); +} + +template +boost::uint32_t cpp_float::mul_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) +{ + boost::uint64_t carry = static_cast(0u); + + // Multiplication loop. + for(boost::int32_t j = p - 1; j >= static_cast(0); j--) + { + const boost::uint64_t t = static_cast(carry + static_cast(u[j] * static_cast(n))); + carry = static_cast(t / static_cast(mp_elem_mask)); + u[j] = static_cast(t - static_cast(static_cast(mp_elem_mask) * static_cast(carry))); + } + + return static_cast(carry); +} + +template +boost::uint32_t cpp_float::div_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) +{ + boost::uint64_t prev = static_cast(0u); + + for(boost::int32_t j = static_cast(0); j < p; j++) + { + const boost::uint64_t t = static_cast(u[j] + static_cast(prev * static_cast(mp_elem_mask))); + u[j] = static_cast(t / n); + prev = static_cast(t - static_cast(n * static_cast(u[j]))); + } + + return static_cast(prev); +} + +template +cpp_float cpp_float::pow2(const boost::int64_t p) +{ + // Create a static const table of p^2 for -128 < p < +128. + // Note: The size of this table must be odd-numbered and + // symmetric about 0. + init.do_nothing(); + static const boost::array, 255u> p2_data = + {{ + cpp_float("5.877471754111437539843682686111228389093327783860437607543758531392086297273635864257812500000000000e-39"), + cpp_float("1.175494350822287507968736537222245677818665556772087521508751706278417259454727172851562500000000000e-38"), + cpp_float("2.350988701644575015937473074444491355637331113544175043017503412556834518909454345703125000000000000e-38"), + cpp_float("4.701977403289150031874946148888982711274662227088350086035006825113669037818908691406250000000000000e-38"), + cpp_float("9.403954806578300063749892297777965422549324454176700172070013650227338075637817382812500000000000000e-38"), + cpp_float("1.880790961315660012749978459555593084509864890835340034414002730045467615127563476562500000000000000e-37"), + cpp_float("3.761581922631320025499956919111186169019729781670680068828005460090935230255126953125000000000000000e-37"), + cpp_float("7.523163845262640050999913838222372338039459563341360137656010920181870460510253906250000000000000000e-37"), + cpp_float("1.504632769052528010199982767644474467607891912668272027531202184036374092102050781250000000000000000e-36"), + cpp_float("3.009265538105056020399965535288948935215783825336544055062404368072748184204101562500000000000000000e-36"), + cpp_float("6.018531076210112040799931070577897870431567650673088110124808736145496368408203125000000000000000000e-36"), + cpp_float("1.203706215242022408159986214115579574086313530134617622024961747229099273681640625000000000000000000e-35"), + cpp_float("2.407412430484044816319972428231159148172627060269235244049923494458198547363281250000000000000000000e-35"), + cpp_float("4.814824860968089632639944856462318296345254120538470488099846988916397094726562500000000000000000000e-35"), + cpp_float("9.629649721936179265279889712924636592690508241076940976199693977832794189453125000000000000000000000e-35"), + cpp_float("1.925929944387235853055977942584927318538101648215388195239938795566558837890625000000000000000000000e-34"), + cpp_float("3.851859888774471706111955885169854637076203296430776390479877591133117675781250000000000000000000000e-34"), + cpp_float("7.703719777548943412223911770339709274152406592861552780959755182266235351562500000000000000000000000e-34"), + cpp_float("1.540743955509788682444782354067941854830481318572310556191951036453247070312500000000000000000000000e-33"), + cpp_float("3.081487911019577364889564708135883709660962637144621112383902072906494140625000000000000000000000000e-33"), + cpp_float("6.162975822039154729779129416271767419321925274289242224767804145812988281250000000000000000000000000e-33"), + cpp_float("1.232595164407830945955825883254353483864385054857848444953560829162597656250000000000000000000000000e-32"), + cpp_float("2.465190328815661891911651766508706967728770109715696889907121658325195312500000000000000000000000000e-32"), + cpp_float("4.930380657631323783823303533017413935457540219431393779814243316650390625000000000000000000000000000e-32"), + cpp_float("9.860761315262647567646607066034827870915080438862787559628486633300781250000000000000000000000000000e-32"), + cpp_float("1.972152263052529513529321413206965574183016087772557511925697326660156250000000000000000000000000000e-31"), + cpp_float("3.944304526105059027058642826413931148366032175545115023851394653320312500000000000000000000000000000e-31"), + cpp_float("7.888609052210118054117285652827862296732064351090230047702789306640625000000000000000000000000000000e-31"), + cpp_float("1.577721810442023610823457130565572459346412870218046009540557861328125000000000000000000000000000000e-30"), + cpp_float("3.155443620884047221646914261131144918692825740436092019081115722656250000000000000000000000000000000e-30"), + cpp_float("6.310887241768094443293828522262289837385651480872184038162231445312500000000000000000000000000000000e-30"), + cpp_float("1.262177448353618888658765704452457967477130296174436807632446289062500000000000000000000000000000000e-29"), + cpp_float("2.524354896707237777317531408904915934954260592348873615264892578125000000000000000000000000000000000e-29"), + cpp_float("5.048709793414475554635062817809831869908521184697747230529785156250000000000000000000000000000000000e-29"), + cpp_float("1.009741958682895110927012563561966373981704236939549446105957031250000000000000000000000000000000000e-28"), + cpp_float("2.019483917365790221854025127123932747963408473879098892211914062500000000000000000000000000000000000e-28"), + cpp_float("4.038967834731580443708050254247865495926816947758197784423828125000000000000000000000000000000000000e-28"), + cpp_float("8.077935669463160887416100508495730991853633895516395568847656250000000000000000000000000000000000000e-28"), + cpp_float("1.615587133892632177483220101699146198370726779103279113769531250000000000000000000000000000000000000e-27"), + cpp_float("3.231174267785264354966440203398292396741453558206558227539062500000000000000000000000000000000000000e-27"), + cpp_float("6.462348535570528709932880406796584793482907116413116455078125000000000000000000000000000000000000000e-27"), + cpp_float("1.292469707114105741986576081359316958696581423282623291015625000000000000000000000000000000000000000e-26"), + cpp_float("2.584939414228211483973152162718633917393162846565246582031250000000000000000000000000000000000000000e-26"), + cpp_float("5.169878828456422967946304325437267834786325693130493164062500000000000000000000000000000000000000000e-26"), + cpp_float("1.033975765691284593589260865087453566957265138626098632812500000000000000000000000000000000000000000e-25"), + cpp_float("2.067951531382569187178521730174907133914530277252197265625000000000000000000000000000000000000000000e-25"), + cpp_float("4.135903062765138374357043460349814267829060554504394531250000000000000000000000000000000000000000000e-25"), + cpp_float("8.271806125530276748714086920699628535658121109008789062500000000000000000000000000000000000000000000e-25"), + cpp_float("1.654361225106055349742817384139925707131624221801757812500000000000000000000000000000000000000000000e-24"), + cpp_float("3.308722450212110699485634768279851414263248443603515625000000000000000000000000000000000000000000000e-24"), + cpp_float("6.617444900424221398971269536559702828526496887207031250000000000000000000000000000000000000000000000e-24"), + cpp_float("1.323488980084844279794253907311940565705299377441406250000000000000000000000000000000000000000000000e-23"), + cpp_float("2.646977960169688559588507814623881131410598754882812500000000000000000000000000000000000000000000000e-23"), + cpp_float("5.293955920339377119177015629247762262821197509765625000000000000000000000000000000000000000000000000e-23"), + cpp_float("1.058791184067875423835403125849552452564239501953125000000000000000000000000000000000000000000000000e-22"), + cpp_float("2.117582368135750847670806251699104905128479003906250000000000000000000000000000000000000000000000000e-22"), + cpp_float("4.235164736271501695341612503398209810256958007812500000000000000000000000000000000000000000000000000e-22"), + cpp_float("8.470329472543003390683225006796419620513916015625000000000000000000000000000000000000000000000000000e-22"), + cpp_float("1.694065894508600678136645001359283924102783203125000000000000000000000000000000000000000000000000000e-21"), + cpp_float("3.388131789017201356273290002718567848205566406250000000000000000000000000000000000000000000000000000e-21"), + cpp_float("6.776263578034402712546580005437135696411132812500000000000000000000000000000000000000000000000000000e-21"), + cpp_float("1.355252715606880542509316001087427139282226562500000000000000000000000000000000000000000000000000000e-20"), + cpp_float("2.710505431213761085018632002174854278564453125000000000000000000000000000000000000000000000000000000e-20"), + cpp_float("5.421010862427522170037264004349708557128906250000000000000000000000000000000000000000000000000000000e-20"), + cpp_float("1.084202172485504434007452800869941711425781250000000000000000000000000000000000000000000000000000000e-19"), + cpp_float("2.168404344971008868014905601739883422851562500000000000000000000000000000000000000000000000000000000e-19"), + cpp_float("4.336808689942017736029811203479766845703125000000000000000000000000000000000000000000000000000000000e-19"), + cpp_float("8.673617379884035472059622406959533691406250000000000000000000000000000000000000000000000000000000000e-19"), + cpp_float("1.734723475976807094411924481391906738281250000000000000000000000000000000000000000000000000000000000e-18"), + cpp_float("3.469446951953614188823848962783813476562500000000000000000000000000000000000000000000000000000000000e-18"), + cpp_float("6.938893903907228377647697925567626953125000000000000000000000000000000000000000000000000000000000000e-18"), + cpp_float("1.387778780781445675529539585113525390625000000000000000000000000000000000000000000000000000000000000e-17"), + cpp_float("2.775557561562891351059079170227050781250000000000000000000000000000000000000000000000000000000000000e-17"), + cpp_float("5.551115123125782702118158340454101562500000000000000000000000000000000000000000000000000000000000000e-17"), + cpp_float("1.110223024625156540423631668090820312500000000000000000000000000000000000000000000000000000000000000e-16"), + cpp_float("2.220446049250313080847263336181640625000000000000000000000000000000000000000000000000000000000000000e-16"), + cpp_float("4.440892098500626161694526672363281250000000000000000000000000000000000000000000000000000000000000000e-16"), + cpp_float("8.881784197001252323389053344726562500000000000000000000000000000000000000000000000000000000000000000e-16"), + cpp_float("1.776356839400250464677810668945312500000000000000000000000000000000000000000000000000000000000000000e-15"), + cpp_float("3.552713678800500929355621337890625000000000000000000000000000000000000000000000000000000000000000000e-15"), + cpp_float("7.105427357601001858711242675781250000000000000000000000000000000000000000000000000000000000000000000e-15"), + cpp_float("1.421085471520200371742248535156250000000000000000000000000000000000000000000000000000000000000000000e-14"), + cpp_float("2.842170943040400743484497070312500000000000000000000000000000000000000000000000000000000000000000000e-14"), + cpp_float("5.684341886080801486968994140625000000000000000000000000000000000000000000000000000000000000000000000e-14"), + cpp_float("1.136868377216160297393798828125000000000000000000000000000000000000000000000000000000000000000000000e-13"), + cpp_float("2.273736754432320594787597656250000000000000000000000000000000000000000000000000000000000000000000000e-13"), + cpp_float("4.547473508864641189575195312500000000000000000000000000000000000000000000000000000000000000000000000e-13"), + cpp_float("9.094947017729282379150390625000000000000000000000000000000000000000000000000000000000000000000000000e-13"), + cpp_float("1.818989403545856475830078125000000000000000000000000000000000000000000000000000000000000000000000000e-12"), + cpp_float("3.637978807091712951660156250000000000000000000000000000000000000000000000000000000000000000000000000e-12"), + cpp_float("7.275957614183425903320312500000000000000000000000000000000000000000000000000000000000000000000000000e-12"), + cpp_float("1.455191522836685180664062500000000000000000000000000000000000000000000000000000000000000000000000000e-11"), + cpp_float("2.910383045673370361328125000000000000000000000000000000000000000000000000000000000000000000000000000e-11"), + cpp_float("5.820766091346740722656250000000000000000000000000000000000000000000000000000000000000000000000000000e-11"), + cpp_float("1.164153218269348144531250000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), + cpp_float("2.328306436538696289062500000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), + cpp_float("4.656612873077392578125000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), + cpp_float("9.313225746154785156250000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), + cpp_float("1.862645149230957031250000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), + cpp_float("3.725290298461914062500000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), + cpp_float("7.450580596923828125000000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), + cpp_float("1.490116119384765625000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), + cpp_float("2.980232238769531250000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), + cpp_float("5.960464477539062500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), + cpp_float("1.192092895507812500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), + cpp_float("2.384185791015625000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), + cpp_float("4.768371582031250000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), + cpp_float("9.536743164062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), + cpp_float("1.907348632812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), + cpp_float("3.814697265625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), + cpp_float("7.629394531250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), + cpp_float("0.000015258789062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000030517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000061035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000122070312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000244140625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000488281250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000976562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.001953125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.003906250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.007812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.01562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.03125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.06250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.125"), + cpp_float("0.25"), + cpp_float("0.5"), + one(), + two(), + cpp_float(static_cast(4)), + cpp_float(static_cast(8)), + cpp_float(static_cast(16)), + cpp_float(static_cast(32)), + cpp_float(static_cast(64)), + cpp_float(static_cast(128)), + cpp_float(static_cast(256)), + cpp_float(static_cast(512)), + cpp_float(static_cast(1024)), + cpp_float(static_cast(2048)), + cpp_float(static_cast(4096)), + cpp_float(static_cast(8192)), + cpp_float(static_cast(16384)), + cpp_float(static_cast(32768)), + cpp_float(static_cast(65536)), + cpp_float(static_cast(131072)), + cpp_float(static_cast(262144)), + cpp_float(static_cast(524288)), + cpp_float(static_cast(1uL << 20u)), + cpp_float(static_cast(1uL << 21u)), + cpp_float(static_cast(1uL << 22u)), + cpp_float(static_cast(1uL << 23u)), + cpp_float(static_cast(1uL << 24u)), + cpp_float(static_cast(1uL << 25u)), + cpp_float(static_cast(1uL << 26u)), + cpp_float(static_cast(1uL << 27u)), + cpp_float(static_cast(1uL << 28u)), + cpp_float(static_cast(1uL << 29u)), + cpp_float(static_cast(1uL << 30u)), + cpp_float(static_cast(1uL << 31u)), + cpp_float(static_cast(1uLL << 32u)), + cpp_float(static_cast(1uLL << 33u)), + cpp_float(static_cast(1uLL << 34u)), + cpp_float(static_cast(1uLL << 35u)), + cpp_float(static_cast(1uLL << 36u)), + cpp_float(static_cast(1uLL << 37u)), + cpp_float(static_cast(1uLL << 38u)), + cpp_float(static_cast(1uLL << 39u)), + cpp_float(static_cast(1uLL << 40u)), + cpp_float(static_cast(1uLL << 41u)), + cpp_float(static_cast(1uLL << 42u)), + cpp_float(static_cast(1uLL << 43u)), + cpp_float(static_cast(1uLL << 44u)), + cpp_float(static_cast(1uLL << 45u)), + cpp_float(static_cast(1uLL << 46u)), + cpp_float(static_cast(1uLL << 47u)), + cpp_float(static_cast(1uLL << 48u)), + cpp_float(static_cast(1uLL << 49u)), + cpp_float(static_cast(1uLL << 50u)), + cpp_float(static_cast(1uLL << 51u)), + cpp_float(static_cast(1uLL << 52u)), + cpp_float(static_cast(1uLL << 53u)), + cpp_float(static_cast(1uLL << 54u)), + cpp_float(static_cast(1uLL << 55u)), + cpp_float(static_cast(1uLL << 56u)), + cpp_float(static_cast(1uLL << 57u)), + cpp_float(static_cast(1uLL << 58u)), + cpp_float(static_cast(1uLL << 59u)), + cpp_float(static_cast(1uLL << 60u)), + cpp_float(static_cast(1uLL << 61u)), + cpp_float(static_cast(1uLL << 62u)), + cpp_float(static_cast(1uLL << 63u)), + cpp_float("1.844674407370955161600000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), + cpp_float("3.689348814741910323200000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), + cpp_float("7.378697629483820646400000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), + cpp_float("1.475739525896764129280000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), + cpp_float("2.951479051793528258560000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), + cpp_float("5.902958103587056517120000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), + cpp_float("1.180591620717411303424000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), + cpp_float("2.361183241434822606848000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), + cpp_float("4.722366482869645213696000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), + cpp_float("9.444732965739290427392000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), + cpp_float("1.888946593147858085478400000000000000000000000000000000000000000000000000000000000000000000000000000e22"), + cpp_float("3.777893186295716170956800000000000000000000000000000000000000000000000000000000000000000000000000000e22"), + cpp_float("7.555786372591432341913600000000000000000000000000000000000000000000000000000000000000000000000000000e22"), + cpp_float("1.511157274518286468382720000000000000000000000000000000000000000000000000000000000000000000000000000e23"), + cpp_float("3.022314549036572936765440000000000000000000000000000000000000000000000000000000000000000000000000000e23"), + cpp_float("6.044629098073145873530880000000000000000000000000000000000000000000000000000000000000000000000000000e23"), + cpp_float("1.208925819614629174706176000000000000000000000000000000000000000000000000000000000000000000000000000e24"), + cpp_float("2.417851639229258349412352000000000000000000000000000000000000000000000000000000000000000000000000000e24"), + cpp_float("4.835703278458516698824704000000000000000000000000000000000000000000000000000000000000000000000000000e24"), + cpp_float("9.671406556917033397649408000000000000000000000000000000000000000000000000000000000000000000000000000e24"), + cpp_float("1.934281311383406679529881600000000000000000000000000000000000000000000000000000000000000000000000000e25"), + cpp_float("3.868562622766813359059763200000000000000000000000000000000000000000000000000000000000000000000000000e25"), + cpp_float("7.737125245533626718119526400000000000000000000000000000000000000000000000000000000000000000000000000e25"), + cpp_float("1.547425049106725343623905280000000000000000000000000000000000000000000000000000000000000000000000000e26"), + cpp_float("3.094850098213450687247810560000000000000000000000000000000000000000000000000000000000000000000000000e26"), + cpp_float("6.189700196426901374495621120000000000000000000000000000000000000000000000000000000000000000000000000e26"), + cpp_float("1.237940039285380274899124224000000000000000000000000000000000000000000000000000000000000000000000000e27"), + cpp_float("2.475880078570760549798248448000000000000000000000000000000000000000000000000000000000000000000000000e27"), + cpp_float("4.951760157141521099596496896000000000000000000000000000000000000000000000000000000000000000000000000e27"), + cpp_float("9.903520314283042199192993792000000000000000000000000000000000000000000000000000000000000000000000000e27"), + cpp_float("1.980704062856608439838598758400000000000000000000000000000000000000000000000000000000000000000000000e28"), + cpp_float("3.961408125713216879677197516800000000000000000000000000000000000000000000000000000000000000000000000e28"), + cpp_float("7.922816251426433759354395033600000000000000000000000000000000000000000000000000000000000000000000000e28"), + cpp_float("1.584563250285286751870879006720000000000000000000000000000000000000000000000000000000000000000000000e29"), + cpp_float("3.169126500570573503741758013440000000000000000000000000000000000000000000000000000000000000000000000e29"), + cpp_float("6.338253001141147007483516026880000000000000000000000000000000000000000000000000000000000000000000000e29"), + cpp_float("1.267650600228229401496703205376000000000000000000000000000000000000000000000000000000000000000000000e30"), + cpp_float("2.535301200456458802993406410752000000000000000000000000000000000000000000000000000000000000000000000e30"), + cpp_float("5.070602400912917605986812821504000000000000000000000000000000000000000000000000000000000000000000000e30"), + cpp_float("1.014120480182583521197362564300800000000000000000000000000000000000000000000000000000000000000000000e31"), + cpp_float("2.028240960365167042394725128601600000000000000000000000000000000000000000000000000000000000000000000e31"), + cpp_float("4.056481920730334084789450257203200000000000000000000000000000000000000000000000000000000000000000000e31"), + cpp_float("8.112963841460668169578900514406400000000000000000000000000000000000000000000000000000000000000000000e31"), + cpp_float("1.622592768292133633915780102881280000000000000000000000000000000000000000000000000000000000000000000e32"), + cpp_float("3.245185536584267267831560205762560000000000000000000000000000000000000000000000000000000000000000000e32"), + cpp_float("6.490371073168534535663120411525120000000000000000000000000000000000000000000000000000000000000000000e32"), + cpp_float("1.298074214633706907132624082305024000000000000000000000000000000000000000000000000000000000000000000e33"), + cpp_float("2.596148429267413814265248164610048000000000000000000000000000000000000000000000000000000000000000000e33"), + cpp_float("5.192296858534827628530496329220096000000000000000000000000000000000000000000000000000000000000000000e33"), + cpp_float("1.038459371706965525706099265844019200000000000000000000000000000000000000000000000000000000000000000e34"), + cpp_float("2.076918743413931051412198531688038400000000000000000000000000000000000000000000000000000000000000000e34"), + cpp_float("4.153837486827862102824397063376076800000000000000000000000000000000000000000000000000000000000000000e34"), + cpp_float("8.307674973655724205648794126752153600000000000000000000000000000000000000000000000000000000000000000e34"), + cpp_float("1.661534994731144841129758825350430720000000000000000000000000000000000000000000000000000000000000000e35"), + cpp_float("3.323069989462289682259517650700861440000000000000000000000000000000000000000000000000000000000000000e35"), + cpp_float("6.646139978924579364519035301401722880000000000000000000000000000000000000000000000000000000000000000e35"), + cpp_float("1.329227995784915872903807060280344576000000000000000000000000000000000000000000000000000000000000000e36"), + cpp_float("2.658455991569831745807614120560689152000000000000000000000000000000000000000000000000000000000000000e36"), + cpp_float("5.316911983139663491615228241121378304000000000000000000000000000000000000000000000000000000000000000e36"), + cpp_float("1.063382396627932698323045648224275660800000000000000000000000000000000000000000000000000000000000000e37"), + cpp_float("2.126764793255865396646091296448551321600000000000000000000000000000000000000000000000000000000000000e37"), + cpp_float("4.253529586511730793292182592897102643200000000000000000000000000000000000000000000000000000000000000e37"), + cpp_float("8.507059173023461586584365185794205286400000000000000000000000000000000000000000000000000000000000000e37"), + cpp_float("1.701411834604692317316873037158841057280000000000000000000000000000000000000000000000000000000000000e38") + }}; + + if((p > static_cast(-128)) && (p < static_cast(+128))) + { + return p2_data[static_cast(p + ((p2_data.size() - 1u) / 2u))]; + } + + // Compute and return 2^p. + if(p < static_cast(0)) + { + return pow2(static_cast(-p)).calculate_inv(); + } + else if(p < static_cast(std::numeric_limits::digits)) + { + const boost::uint64_t p2 = static_cast(static_cast(1uLL) << p); + return cpp_float(p2); + } + else + { + cpp_float t; + default_ops::detail::pow_imp(t, two(), p, mpl::true_()); + return t; + } +} + + +template +inline void add(cpp_float& result, const cpp_float& o) +{ + result += o; +} +template +inline void subtract(cpp_float& result, const cpp_float& o) +{ + result -= o; +} +template +inline void multiply(cpp_float& result, const cpp_float& o) +{ + result *= o; +} +template +inline void divide(cpp_float& result, const cpp_float& o) +{ + result /= o; +} + +template +inline void add(cpp_float& result, const unsigned long long& o) +{ + result.add_unsigned_long_long(o); +} +template +inline void subtract(cpp_float& result, const unsigned long long& o) +{ + result.sub_unsigned_long_long(o); +} +template +inline void multiply(cpp_float& result, const unsigned long long& o) +{ + result.mul_unsigned_long_long(o); +} +template +inline void divide(cpp_float& result, const unsigned long long& o) +{ + result.div_unsigned_long_long(o); +} + +template +inline void add(cpp_float& result, long long o) +{ + if(o < 0) + result.sub_unsigned_long_long(-o); + else + result.add_unsigned_long_long(o); +} +template +inline void subtract(cpp_float& result, long long o) +{ + if(o < 0) + result.add_unsigned_long_long(-o); + else + result.sub_unsigned_long_long(o); +} +template +inline void multiply(cpp_float& result, long long o) +{ + if(o < 0) + { + result.mul_unsigned_long_long(-o); + result.negate(); + } + else + result.mul_unsigned_long_long(o); +} +template +inline void divide(cpp_float& result, long long o) +{ + if(o < 0) + { + result.div_unsigned_long_long(-o); + result.negate(); + } + else + result.div_unsigned_long_long(o); +} + +template +inline void convert_to(unsigned long long* result, const cpp_float& val) +{ + *result = val.extract_unsigned_long_long(); +} +template +inline void convert_to(long long* result, const cpp_float& val) +{ + *result = val.extract_signed_long_long(); +} +template +inline void convert_to(long double* result, cpp_float& val) +{ + *result = val.extract_long_double(); +} + +// +// Non member function support: +// +template +inline int eval_fpclassify(const cpp_float& x) +{ + if(x.isinf()) + return FP_INFINITE; + if(x.isnan()) + return FP_NAN; + if(x.iszero()) + return FP_ZERO; + return FP_NORMAL; +} + +template +inline void eval_abs(cpp_float& result, const cpp_float& x) +{ + result = x; + if(x.isneg()) + result.negate(); +} + +template +inline void eval_fabs(cpp_float& result, const cpp_float& x) +{ + result = x; + if(x.isneg()) + result.negate(); +} + +template +inline void eval_sqrt(cpp_float& result, const cpp_float& x) +{ + result = x; + result.calculate_sqrt(); +} + +template +inline void eval_floor(cpp_float& result, const cpp_float& x) +{ + result = x; + if(!x.isfinite() || x.isint()) + { + return; + } + + if(x.isneg()) + result -= cpp_float::one(); + result = result.extract_integer_part(); +} + +template +inline void eval_ceil(cpp_float& result, const cpp_float& x) +{ + result = x; + if(!x.isfinite() || x.isint()) + { + return; + } + + if(!x.isneg()) + result += cpp_float::one(); + result = result.extract_integer_part(); +} + +template +inline void eval_trunc(cpp_float& result, const cpp_float& x) +{ + if(!x.isfinite()) + { + result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, mp_number >(x), 0, boost::math::policies::policy<>()).backend(); + return; + } + else if(x.isint()) + { + result = x; + return; + } + result = x.extract_integer_part(); +} + +template +inline void eval_ldexp(cpp_float& result, const cpp_float& x, long long e) +{ + result = x; + result *= cpp_float::pow2(e); +} + +template +inline void eval_frexp(cpp_float& result, const cpp_float& x, long long* e) +{ + result = x; + if(result.isneg()) + result.negate(); + + long long t = result.order(); + + if(std::abs(t) > (std::numeric_limits::max)() / 3) + throw std::runtime_error("Exponent is too large to be represented as a power of 2."); + t *= 3; + + result *= cpp_float::pow2(-t); + + while(result.compare(cpp_float::one()) >= 0) + { + result /= cpp_float::two(); + ++t; + } + while(result.compare(cpp_float::half()) < 0) + { + result *= cpp_float::two(); + --t; + } + *e = t; + if(x.isneg()) + result.negate(); +} + +template +inline void eval_frexp(cpp_float& result, const cpp_float& x, int* e) +{ + long long t; + eval_frexp(result, x, &t); + if(t > (std::numeric_limits::max)()) + throw std::runtime_error("Exponent is outside the range of an int"); + *e = static_cast(t); +} + +typedef mp_number > cpp_float_50; +typedef mp_number > cpp_float_100; + +}} + +namespace std +{ + template + class numeric_limits > > + { + public: + static const bool is_specialized = true; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const bool is_bounded = true; + static const bool is_modulo = false; + static const bool is_iec559 = false; + static const int digits = static_cast(((Digits10 + 1) * 1000L) / 301L); + static const int digits10 = boost::multiprecision::cpp_float::cpp_float_digits10; + static const int max_digits10 = boost::multiprecision::cpp_float::cpp_float_max_digits10; + static const boost::int64_t min_exponent = boost::multiprecision::cpp_float::cpp_float_min_exp; // Type differs from int. + static const boost::int64_t min_exponent10 = boost::multiprecision::cpp_float::cpp_float_min_exp10; // Type differs from int. + static const boost::int64_t max_exponent = boost::multiprecision::cpp_float::cpp_float_max_exp; // Type differs from int. + static const boost::int64_t max_exponent10 = boost::multiprecision::cpp_float::cpp_float_max_exp10; // Type differs from int. + static const int radix = boost::multiprecision::cpp_float::mp_radix; + static const std::float_round_style round_style = std::round_to_nearest; + static const bool has_infinity = true; + static const bool has_quiet_NaN = true; + static const bool has_signaling_NaN = false; + static const std::float_denorm_style has_denorm = std::denorm_absent; + static const bool has_denorm_loss = false; + static const bool traps = false; + static const bool tinyness_before = false; + + static const boost::multiprecision::mp_number > (min) (void) throw() { return (boost::multiprecision::cpp_float::min)(); } + static const boost::multiprecision::mp_number > (max) (void) throw() { return (boost::multiprecision::cpp_float::max)(); } + static const boost::multiprecision::mp_number > lowest (void) throw() { return boost::multiprecision::cpp_float::zero(); } + static const boost::multiprecision::mp_number > epsilon (void) throw() { return boost::multiprecision::cpp_float::eps(); } + static const boost::multiprecision::mp_number > round_error (void) throw() { return 0.5L; } + static const boost::multiprecision::mp_number > infinity (void) throw() { return boost::multiprecision::cpp_float::inf(); } + static const boost::multiprecision::mp_number > quiet_NaN (void) throw() { return boost::multiprecision::cpp_float::nan(); } + static const boost::multiprecision::mp_number > signaling_NaN(void) throw() { return boost::multiprecision::cpp_float::zero(); } + static const boost::multiprecision::mp_number > denorm_min (void) throw() { return boost::multiprecision::cpp_float::zero(); } + }; +} + +namespace boost{ namespace math{ + +namespace policies{ + +template +struct precision< boost::multiprecision::mp_number >, Policy> +{ + typedef typename Policy::precision_type precision_type; + typedef digits2<((Digits10 + 1) * 1000L) / 301L> digits_2; + typedef typename mpl::if_c< + ((digits_2::value <= precision_type::value) + || (Policy::precision_type::value <= 0)), + // Default case, full precision for RealType: + digits_2, + // User customised precision: + precision_type + >::type type; +}; + +} // namespace policies + +}} // namespaces boost::math + + +#endif + diff --git a/include/boost/multiprecision/mp_float.hpp b/include/boost/multiprecision/mp_float.hpp index dc7fd375..13c41251 100644 --- a/include/boost/multiprecision/mp_float.hpp +++ b/include/boost/multiprecision/mp_float.hpp @@ -25,7 +25,7 @@ namespace boost{ namespace multiprecision{ template -class mp_float +class cpp_float { public: typedef mpl::list signed_types; @@ -35,22 +35,22 @@ public: static const boost::int32_t mp_radix = 10; - static const boost::int32_t mp_float_digits = Digits10; + static const boost::int32_t cpp_float_digits = Digits10; - static const boost::int32_t mp_float_digits10_setting = Digits10; - static const boost::int32_t mp_float_digits10_limit = boost::integer_traits::const_max; - static const boost::int32_t mp_float_digits10 = ((mp_float_digits10_setting < static_cast(30)) ? static_cast(30) : ((mp_float_digits10_setting > mp_float_digits10_limit) ? mp_float_digits10_limit : mp_float_digits10_setting)); - static const boost::int32_t mp_float_digits10_extra = static_cast(((static_cast(mp_float_digits10) * 15LL) + 50LL) / 100LL); - static const boost::int32_t mp_float_max_digits10 = static_cast(mp_float_digits10 + ((mp_float_digits10_extra < static_cast(5)) ? static_cast(5) : ((mp_float_digits10_extra > static_cast(30)) ? static_cast(30) : mp_float_digits10_extra))); - static const boost::int64_t mp_float_max_exp = static_cast(+9223372036854775795LL); - static const boost::int64_t mp_float_min_exp = static_cast(-9223372036854775795LL); - static const boost::int64_t mp_float_max_exp10 = static_cast(+3063937869882635616LL); // Approx. [mp_float_max_exp / log10(2)], also an even multiple of 8 - static const boost::int64_t mp_float_min_exp10 = static_cast(-3063937869882635616LL); + static const boost::int32_t cpp_float_digits10_setting = Digits10; + static const boost::int32_t cpp_float_digits10_limit = boost::integer_traits::const_max; + static const boost::int32_t cpp_float_digits10 = ((cpp_float_digits10_setting < static_cast(30)) ? static_cast(30) : ((cpp_float_digits10_setting > cpp_float_digits10_limit) ? cpp_float_digits10_limit : cpp_float_digits10_setting)); + static const boost::int32_t cpp_float_digits10_extra = static_cast(((static_cast(cpp_float_digits10) * 15LL) + 50LL) / 100LL); + static const boost::int32_t cpp_float_max_digits10 = static_cast(cpp_float_digits10 + ((cpp_float_digits10_extra < static_cast(5)) ? static_cast(5) : ((cpp_float_digits10_extra > static_cast(30)) ? static_cast(30) : cpp_float_digits10_extra))); + static const boost::int64_t cpp_float_max_exp = static_cast(+9223372036854775795LL); + static const boost::int64_t cpp_float_min_exp = static_cast(-9223372036854775795LL); + static const boost::int64_t cpp_float_max_exp10 = static_cast(+3063937869882635616LL); // Approx. [cpp_float_max_exp / log10(2)], also an even multiple of 8 + static const boost::int64_t cpp_float_min_exp10 = static_cast(-3063937869882635616LL); static const boost::int32_t mp_elem_digits10 = static_cast(8); private: - static const boost::int32_t mp_float_digits10_num_base = static_cast((mp_float_max_digits10 / mp_elem_digits10) + (((mp_float_max_digits10 % mp_elem_digits10) != 0) ? 1 : 0)); - static const boost::int32_t mp_elem_number = static_cast(mp_float_digits10_num_base + 2); + static const boost::int32_t cpp_float_digits10_num_base = static_cast((cpp_float_max_digits10 / mp_elem_digits10) + (((cpp_float_max_digits10 % mp_elem_digits10) != 0) ? 1 : 0)); + static const boost::int32_t mp_elem_number = static_cast(cpp_float_digits10_num_base + 2); static const boost::int32_t mp_elem_mask = static_cast(100000000); typedef enum enum_fpclass @@ -72,7 +72,7 @@ private: // // Special values constructor: // - mp_float(t_fpclass c) : + cpp_float(t_fpclass c) : data(), exp (static_cast(0)), neg (false), @@ -86,23 +86,23 @@ private: { initializer() { - mp_float::nan(); - mp_float::inf(); - (mp_float::min)(); - (mp_float::max)(); - mp_float::zero(); - mp_float::one(); - mp_float::two(); - mp_float::half(); - mp_float::double_min(); - mp_float::double_max(); - mp_float::long_double_max(); - mp_float::long_double_min(); - mp_float::long_long_max(); - mp_float::long_long_min(); - mp_float::ulong_long_max(); - mp_float::eps(); - mp_float::pow2(0); + cpp_float::nan(); + cpp_float::inf(); + (cpp_float::min)(); + (cpp_float::max)(); + cpp_float::zero(); + cpp_float::one(); + cpp_float::two(); + cpp_float::half(); + cpp_float::double_min(); + cpp_float::double_max(); + cpp_float::long_double_max(); + cpp_float::long_double_min(); + cpp_float::long_long_max(); + cpp_float::long_long_min(); + cpp_float::ulong_long_max(); + cpp_float::eps(); + cpp_float::pow2(0); } void do_nothing(){} }; @@ -111,14 +111,14 @@ private: public: // Constructors - mp_float() : + cpp_float() : data(), exp (static_cast(0)), neg (false), fpclass (mp_finite), prec_elem(mp_elem_number) { } - mp_float(const char* s) : + cpp_float(const char* s) : data(), exp (static_cast(0)), neg (false), @@ -129,7 +129,7 @@ public: } template - mp_float(I i, typename enable_if >::type* = 0) : + cpp_float(I i, typename enable_if >::type* = 0) : data(), exp (static_cast(0)), neg (false), @@ -140,7 +140,7 @@ public: } template - mp_float(I i, typename enable_if >::type* = 0) : + cpp_float(I i, typename enable_if >::type* = 0) : data(), exp (static_cast(0)), neg (false), @@ -156,7 +156,7 @@ public: from_unsigned_long_long(i); } - mp_float(const mp_float& f) : + cpp_float(const cpp_float& f) : data (f.data), exp (f.exp), neg (f.neg), @@ -164,7 +164,7 @@ public: prec_elem(f.prec_elem) { } template - mp_float(const F val, typename enable_if >::type* = 0): + cpp_float(const F val, typename enable_if >::type* = 0): data(), exp (static_cast(0)), neg (false), @@ -174,28 +174,28 @@ public: *this = val; } - mp_float(const double val, long long exponent); + cpp_float(const double val, long long exponent); // Specific special values. - static const mp_float& nan() + static const cpp_float& nan() { - static const mp_float val(mp_NaN); + static const cpp_float val(mp_NaN); init.do_nothing(); return val; } - static const mp_float& inf() + static const cpp_float& inf() { - static const mp_float val(mp_inf); + static const cpp_float val(mp_inf); init.do_nothing(); return val; } - static const mp_float& (max)() + static const cpp_float& (max)() { init.do_nothing(); static bool init = false; - static const std::string str_max = std::string("9." + std::string(static_cast(mp_float_max_digits10), static_cast('9'))) - + std::string("e+" + boost::lexical_cast(mp_float_max_exp10)); - static mp_float val_max; + static const std::string str_max = std::string("9." + std::string(static_cast(cpp_float_max_digits10), static_cast('9'))) + + std::string("e+" + boost::lexical_cast(cpp_float_max_exp10)); + static cpp_float val_max; if(!init) { init = true; @@ -204,93 +204,93 @@ public: return val_max; } - static const mp_float& (min)() + static const cpp_float& (min)() { init.do_nothing(); static bool init = false; - static mp_float val_min; + static cpp_float val_min; if(!init) { init = true; - val_min = std::string("1.0e" + boost::lexical_cast(mp_float_min_exp10)).c_str(); + val_min = std::string("1.0e" + boost::lexical_cast(cpp_float_min_exp10)).c_str(); } return val_min; } - static const mp_float& zero() + static const cpp_float& zero() { init.do_nothing(); - static mp_float val(static_cast(0u)); + static cpp_float val(static_cast(0u)); return val; } - static const mp_float& one() + static const cpp_float& one() { init.do_nothing(); - static mp_float val(static_cast(1u)); + static cpp_float val(static_cast(1u)); return val; } - static const mp_float& two() + static const cpp_float& two() { init.do_nothing(); - static mp_float val(static_cast(2u)); + static cpp_float val(static_cast(2u)); return val; } - static const mp_float& half() + static const cpp_float& half() { init.do_nothing(); - static mp_float val(0.5L); + static cpp_float val(0.5L); return val; } - static const mp_float& double_min() + static const cpp_float& double_min() { init.do_nothing(); - static mp_float val(static_cast((std::numeric_limits::min)())); + static cpp_float val(static_cast((std::numeric_limits::min)())); return val; } - static const mp_float& double_max() + static const cpp_float& double_max() { init.do_nothing(); - static mp_float val(static_cast((std::numeric_limits::max)())); + static cpp_float val(static_cast((std::numeric_limits::max)())); return val; } - static const mp_float& long_double_min() + static const cpp_float& long_double_min() { init.do_nothing(); - static mp_float val((std::numeric_limits::min)()); + static cpp_float val((std::numeric_limits::min)()); return val; } - static const mp_float& long_double_max() + static const cpp_float& long_double_max() { init.do_nothing(); - static mp_float val((std::numeric_limits::max)()); + static cpp_float val((std::numeric_limits::max)()); return val; } - static const mp_float& long_long_max() + static const cpp_float& long_long_max() { init.do_nothing(); - static mp_float val((std::numeric_limits::max)()); + static cpp_float val((std::numeric_limits::max)()); return val; } - static const mp_float& long_long_min() + static const cpp_float& long_long_min() { init.do_nothing(); - static mp_float val((std::numeric_limits::min)()); + static cpp_float val((std::numeric_limits::min)()); return val; } - static const mp_float& ulong_long_max() + static const cpp_float& ulong_long_max() { init.do_nothing(); - static mp_float val((std::numeric_limits::max)()); + static cpp_float val((std::numeric_limits::max)()); return val; } - static const mp_float& eps() + static const cpp_float& eps() { init.do_nothing(); - static mp_float val(1.0, 1 - (int)Digits10); + static cpp_float val(1.0, 1 - (int)Digits10); return val; } // Basic operations. - mp_float& operator= (const mp_float& v) + cpp_float& operator= (const cpp_float& v) { data = v.data; exp = v.exp; @@ -299,7 +299,7 @@ public: prec_elem = v.prec_elem; return *this; } - mp_float& operator= (long long v) + cpp_float& operator= (long long v) { if(v < 0) { @@ -310,41 +310,41 @@ public: from_unsigned_long_long(v); return *this; } - mp_float& operator= (unsigned long long v) + cpp_float& operator= (unsigned long long v) { from_unsigned_long_long(v); return *this; } - mp_float& operator= (long double v); - mp_float& operator= (const char* v) + cpp_float& operator= (long double v); + cpp_float& operator= (const char* v) { rd_string(v); return *this; } - mp_float& operator+=(const mp_float& v); - mp_float& operator-=(const mp_float& v); - mp_float& operator*=(const mp_float& v); - mp_float& operator/=(const mp_float& v); + cpp_float& operator+=(const cpp_float& v); + cpp_float& operator-=(const cpp_float& v); + cpp_float& operator*=(const cpp_float& v); + cpp_float& operator/=(const cpp_float& v); - mp_float& add_unsigned_long_long(const unsigned long long n) + cpp_float& add_unsigned_long_long(const unsigned long long n) { - mp_float t; + cpp_float t; t.from_unsigned_long_long(n); return *this += t; } - mp_float& sub_unsigned_long_long(const unsigned long long n) + cpp_float& sub_unsigned_long_long(const unsigned long long n) { - mp_float t; + cpp_float t; t.from_unsigned_long_long(n); return *this -= t; } - mp_float& mul_unsigned_long_long(const unsigned long long n); - mp_float& div_unsigned_long_long(const unsigned long long n); + cpp_float& mul_unsigned_long_long(const unsigned long long n); + cpp_float& div_unsigned_long_long(const unsigned long long n); // Elementary primitives. - mp_float& calculate_inv (void); - mp_float& calculate_sqrt(void); + cpp_float& calculate_inv (void); + cpp_float& calculate_sqrt(void); void negate() { if(!iszero()) @@ -365,27 +365,27 @@ public: bool isneg (void) const { return neg; } // Operators pre-increment and pre-decrement - mp_float& operator++(void) + cpp_float& operator++(void) { return *this += one(); } - mp_float& operator--(void) + cpp_float& operator--(void) { return *this -= one(); } std::string str(unsigned digits, bool scientific)const; - int compare(const mp_float& v)const; + int compare(const cpp_float& v)const; template int compare(const V& v)const { - mp_float t; + cpp_float t; t = v; return compare(t); } - void swap(mp_float& v) + void swap(cpp_float& v) { data.swap(v.data); std::swap(exp, v.exp); @@ -399,10 +399,10 @@ public: signed long long extract_signed_long_long (void) const; unsigned long long extract_unsigned_long_long(void) const; void extract_parts (double& mantissa, boost::int64_t& exponent) const; - mp_float extract_integer_part (void) const; + cpp_float extract_integer_part (void) const; void precision(const boost::int32_t prec_digits) { - if(prec_digits >= mp_float_digits10) + if(prec_digits >= cpp_float_digits10) { prec_elem = mp_elem_number; } @@ -414,7 +414,7 @@ public: prec_elem = (std::min)(mp_elem_number, (std::max)(elems, static_cast(2))); } } - static mp_float pow2(long long i); + static cpp_float pow2(long long i); long long order()const { const bool bo_order_is_zero = ((!isfinite()) || (data[0] == static_cast(0u))); @@ -469,7 +469,7 @@ public: private: static bool data_elem_is_non_zero_predicate(const boost::uint32_t& d) { return (d != static_cast(0u)); } - static bool data_elem_is_non_nine_predicate(const boost::uint32_t& d) { return (d != static_cast(mp_float::mp_elem_mask - 1)); } + static bool data_elem_is_non_nine_predicate(const boost::uint32_t& d) { return (d != static_cast(cpp_float::mp_elem_mask - 1)); } static bool char_is_nonzero_predicate(const char& c) { return (c != static_cast('0')); } void from_unsigned_long_long(const unsigned long long u); @@ -484,42 +484,42 @@ private: }; template -typename mp_float::initializer mp_float::init; +typename cpp_float::initializer cpp_float::init; template -const boost::int32_t mp_float::mp_radix; +const boost::int32_t cpp_float::mp_radix; template -const boost::int32_t mp_float::mp_float_digits; +const boost::int32_t cpp_float::cpp_float_digits; template -const boost::int32_t mp_float::mp_float_digits10_setting; +const boost::int32_t cpp_float::cpp_float_digits10_setting; template -const boost::int32_t mp_float::mp_float_digits10_limit; +const boost::int32_t cpp_float::cpp_float_digits10_limit; template -const boost::int32_t mp_float::mp_float_digits10; +const boost::int32_t cpp_float::cpp_float_digits10; template -const boost::int32_t mp_float::mp_float_digits10_extra; +const boost::int32_t cpp_float::cpp_float_digits10_extra; template -const boost::int32_t mp_float::mp_float_max_digits10; +const boost::int32_t cpp_float::cpp_float_max_digits10; template -const boost::int64_t mp_float::mp_float_max_exp; +const boost::int64_t cpp_float::cpp_float_max_exp; template -const boost::int64_t mp_float::mp_float_min_exp; +const boost::int64_t cpp_float::cpp_float_min_exp; template -const boost::int64_t mp_float::mp_float_max_exp10; +const boost::int64_t cpp_float::cpp_float_max_exp10; template -const boost::int64_t mp_float::mp_float_min_exp10; +const boost::int64_t cpp_float::cpp_float_min_exp10; template -const boost::int32_t mp_float::mp_elem_digits10; +const boost::int32_t cpp_float::mp_elem_digits10; template -const boost::int32_t mp_float::mp_float_digits10_num_base; +const boost::int32_t cpp_float::cpp_float_digits10_num_base; template -const boost::int32_t mp_float::mp_elem_number; +const boost::int32_t cpp_float::mp_elem_number; template -const boost::int32_t mp_float::mp_elem_mask; +const boost::int32_t cpp_float::mp_elem_mask; template -mp_float& mp_float::operator+=(const mp_float& v) +cpp_float& cpp_float::operator+=(const cpp_float& v) { if(isnan()) { @@ -709,13 +709,13 @@ mp_float& mp_float::operator+=(const mp_float& v) return *this = zero(); } - bool overflow = exp >= mp_float_max_exp; - if(exp == mp_float_max_exp) + bool overflow = exp >= cpp_float_max_exp; + if(exp == cpp_float_max_exp) { // Check to see if we really truely have an overflow or not... if(isneg()) { - mp_float t(*this); + cpp_float t(*this); t.negate(); overflow = t.compare((max)()) > 0; } @@ -739,7 +739,7 @@ mp_float& mp_float::operator+=(const mp_float& v) } template -mp_float& mp_float::operator-=(const mp_float& v) +cpp_float& cpp_float::operator-=(const cpp_float& v) { // Use *this - v = -(-*this + v). negate(); @@ -749,7 +749,7 @@ mp_float& mp_float::operator-=(const mp_float& v) } template -mp_float& mp_float::operator*=(const mp_float& v) +cpp_float& cpp_float::operator*=(const cpp_float& v) { // Evaluate the sign of the result. const bool b_result_is_neg = (neg != v.neg); @@ -796,7 +796,7 @@ mp_float& mp_float::operator*=(const mp_float& v) const boost::int64_t v_exp = ((!v_exp_is_neg) ? v.exp : static_cast(-v.exp)); // Check the range of the upcoming multiplication. - const bool b_result_is_out_of_range = (v_exp >= static_cast(mp_float_max_exp10 - u_exp)); + const bool b_result_is_out_of_range = (v_exp >= static_cast(cpp_float_max_exp10 - u_exp)); if(b_result_is_out_of_range) { @@ -841,7 +841,7 @@ mp_float& mp_float::operator*=(const mp_float& v) } template -mp_float& mp_float::operator/=(const mp_float& v) +cpp_float& cpp_float::operator/=(const cpp_float& v) { const bool u_and_v_are_finite_and_identical = ( isfinite() && (fpclass == v.fpclass) @@ -865,14 +865,14 @@ mp_float& mp_float::operator/=(const mp_float& v) } return *this; } - mp_float t(v); + cpp_float t(v); t.calculate_inv(); return operator*=(t); } } template -mp_float& mp_float::mul_unsigned_long_long(const unsigned long long n) +cpp_float& cpp_float::mul_unsigned_long_long(const unsigned long long n) { // Multiply *this with a constant unsigned long long. @@ -908,7 +908,7 @@ mp_float& mp_float::mul_unsigned_long_long(const unsigned lo if(n >= static_cast(mp_elem_mask)) { neg = b_neg; - mp_float t; + cpp_float t; t = n; return operator*=(t); } @@ -936,13 +936,13 @@ mp_float& mp_float::mul_unsigned_long_long(const unsigned lo data.front() = static_cast(carry); } - bool overflow = exp >= mp_float_max_exp; - if(exp == mp_float_max_exp) + bool overflow = exp >= cpp_float_max_exp; + if(exp == cpp_float_max_exp) { // Check to see if we really truely have an overflow or not... if(isneg()) { - mp_float t(*this); + cpp_float t(*this); t.negate(); overflow = t.compare((max)()) > 0; } @@ -967,7 +967,7 @@ mp_float& mp_float::mul_unsigned_long_long(const unsigned lo } template -mp_float& mp_float::div_unsigned_long_long(const unsigned long long n) +cpp_float& cpp_float::div_unsigned_long_long(const unsigned long long n) { // Divide *this by a constant unsigned long long. @@ -1016,7 +1016,7 @@ mp_float& mp_float::div_unsigned_long_long(const unsigned lo if(n >= static_cast(mp_elem_mask)) { neg = b_neg; - mp_float t; + cpp_float t; t = n; return operator/=(t); } @@ -1056,7 +1056,7 @@ mp_float& mp_float::div_unsigned_long_long(const unsigned lo } template -mp_float& mp_float::calculate_inv() +cpp_float& cpp_float::calculate_inv() { // Compute the inverse of *this. const bool b_neg = neg; @@ -1090,7 +1090,7 @@ mp_float& mp_float::calculate_inv() } // Save the original *this. - mp_float x(*this); + cpp_float x(*this); // Generate the initial estimate using division. // Extract the mantissa and exponent for a "manual" @@ -1100,7 +1100,7 @@ mp_float& mp_float::calculate_inv() x.extract_parts(dd, ne); // Do the inverse estimate using double precision estimates of mantissa and exponent. - operator=(mp_float(1.0 / dd, -ne)); + operator=(cpp_float(1.0 / dd, -ne)); // Compute the inverse of *this. Quadratically convergent Newton-Raphson iteration // is used. During the iterative steps, the precision of the calculation is limited @@ -1115,7 +1115,7 @@ mp_float& mp_float::calculate_inv() x.precision(static_cast(digits * static_cast(2))); // Next iteration. - mp_float t(*this); + cpp_float t(*this); t *= x; t -= two(); t.negate(); @@ -1130,7 +1130,7 @@ mp_float& mp_float::calculate_inv() } template -mp_float& mp_float::calculate_sqrt(void) +cpp_float& cpp_float::calculate_sqrt(void) { // Compute the square root of *this. @@ -1146,7 +1146,7 @@ mp_float& mp_float::calculate_sqrt(void) } // Save the original *this. - mp_float x(*this); + cpp_float x(*this); // Generate the initial estimate using division. // Extract the mantissa and exponent for a "manual" @@ -1166,10 +1166,10 @@ mp_float& mp_float::calculate_sqrt(void) // Estimate the square root using simple manipulations. const double sqd = std::sqrt(dd); - *this = mp_float(sqd, static_cast(ne / static_cast(2))); + *this = cpp_float(sqd, static_cast(ne / static_cast(2))); // Estimate 1.0 / (2.0 * x0) using simple manipulations. - mp_float vi(0.5 / sqd, static_cast(-ne / static_cast(2))); + cpp_float vi(0.5 / sqd, static_cast(-ne / static_cast(2))); // Compute the square root of x. Coupled Newton iteration // as described in "Pi Unleashed" is used. During the @@ -1190,7 +1190,7 @@ mp_float& mp_float::calculate_sqrt(void) vi.precision(digits * 2); // Next iteration of vi - mp_float t(*this); + cpp_float t(*this); t *= vi; t.negate(); t.mul_unsigned_long_long(2u); @@ -1213,7 +1213,7 @@ mp_float& mp_float::calculate_sqrt(void) } template -int mp_float::cmp_data(const array_type& vd) const +int cpp_float::cmp_data(const array_type& vd) const { // Compare the data of *this with those of v. // Return +1 for *this > v @@ -1235,7 +1235,7 @@ int mp_float::cmp_data(const array_type& vd) const } template -int mp_float::compare(const mp_float& v) const +int cpp_float::compare(const cpp_float& v) const { // Compare v with *this. // Return +1 for *this > v @@ -1313,7 +1313,7 @@ int mp_float::compare(const mp_float& v) const } template -bool mp_float::isone() const +bool cpp_float::isone() const { // Check if the value of *this is identically 1 or very close to 1. @@ -1337,7 +1337,7 @@ bool mp_float::isone() const } template -bool mp_float::isint() const +bool cpp_float::isint() const { if(fpclass != mp_finite) { return false; } @@ -1360,9 +1360,9 @@ bool mp_float::isint() const } template -void mp_float::extract_parts(double& mantissa, boost::int64_t& exponent) const +void cpp_float::extract_parts(double& mantissa, boost::int64_t& exponent) const { - // Extract the approximate parts mantissa and base-10 exponent from the input mp_float value x. + // Extract the approximate parts mantissa and base-10 exponent from the input cpp_float value x. // Extracts the mantissa and exponent. exponent = exp; @@ -1393,11 +1393,11 @@ void mp_float::extract_parts(double& mantissa, boost::int64_t& exponen } template -double mp_float::extract_double(void) const +double cpp_float::extract_double(void) const { - // Returns the double conversion of a mp_float. + // Returns the double conversion of a cpp_float. - // Check for non-normal mp_float. + // Check for non-normal cpp_float. if(!isfinite()) { if(isnan()) @@ -1411,17 +1411,17 @@ double mp_float::extract_double(void) const } } - mp_float xx(*this); + cpp_float xx(*this); if(xx.isneg()) xx.negate(); - // Check for zero mp_float. + // Check for zero cpp_float. if(iszero() || (xx.compare(double_min()) < 0)) { return 0.0; } - // Check if mp_float exceeds the maximum of double. + // Check if cpp_float exceeds the maximum of double. if(xx.compare(double_max()) > 0) { return ((!neg) ? std::numeric_limits::infinity() @@ -1439,11 +1439,11 @@ double mp_float::extract_double(void) const } template -long double mp_float::extract_long_double(void) const +long double cpp_float::extract_long_double(void) const { - // Returns the long double conversion of a mp_float. + // Returns the long double conversion of a cpp_float. - // Check for non-normal mp_float. + // Check for non-normal cpp_float. if(!isfinite()) { if(isnan()) @@ -1457,17 +1457,17 @@ long double mp_float::extract_long_double(void) const } } - mp_float xx(*this); + cpp_float xx(*this); if(xx.isneg()) xx.negate(); - // Check for zero mp_float. + // Check for zero cpp_float. if(iszero() || (xx.compare(long_double_min()) < 0)) { return static_cast(0.0); } - // Check if mp_float exceeds the maximum of double. + // Check if cpp_float exceeds the maximum of double. if(xx.compare(long_double_max()) > 0) { return ((!neg) ? std::numeric_limits::infinity() @@ -1485,7 +1485,7 @@ long double mp_float::extract_long_double(void) const } template -signed long long mp_float::extract_signed_long_long(void) const +signed long long cpp_float::extract_signed_long_long(void) const { // Extracts a signed long long from *this. // If (x > maximum of signed long long) or (x < minimum of signed long long), @@ -1511,7 +1511,7 @@ signed long long mp_float::extract_signed_long_long(void) const else { // Extract the data into an unsigned long long value. - mp_float xn(extract_integer_part()); + cpp_float xn(extract_integer_part()); if(xn.isneg()) xn.negate(); @@ -1530,7 +1530,7 @@ signed long long mp_float::extract_signed_long_long(void) const } template -unsigned long long mp_float::extract_unsigned_long_long(void) const +unsigned long long cpp_float::extract_unsigned_long_long(void) const { // Extracts an unsigned long long from *this. // If x exceeds the maximum of unsigned long long, @@ -1548,7 +1548,7 @@ unsigned long long mp_float::extract_unsigned_long_long(void) const return static_cast(0u); } - const mp_float xn(extract_integer_part()); + const cpp_float xn(extract_integer_part()); unsigned long long val; @@ -1574,7 +1574,7 @@ unsigned long long mp_float::extract_unsigned_long_long(void) const } template -mp_float mp_float::extract_integer_part(void) const +cpp_float cpp_float::extract_integer_part(void) const { // Compute the signed integer part of x. @@ -1597,7 +1597,7 @@ mp_float mp_float::extract_integer_part(void) const } // Make a local copy. - mp_float x = *this; + cpp_float x = *this; // Clear out the decimal portion const size_t first_clear = (static_cast(x.exp) / static_cast(mp_elem_digits10)) + 1u; @@ -1609,20 +1609,20 @@ mp_float mp_float::extract_integer_part(void) const } template -std::string mp_float::str(std::size_t number_of_digits, bool scientific) const +std::string cpp_float::str(std::size_t number_of_digits, bool scientific) const { std::string str; boost::int64_t my_exp = order(); if(number_of_digits == 0) number_of_digits = (std::numeric_limits::max)(); - // Determine the number of elements needed to provide the requested digits from mp_float. + // Determine the number of elements needed to provide the requested digits from cpp_float. const std::size_t number_of_elements = (std::min)(static_cast((number_of_digits / static_cast(mp_elem_digits10)) + 2u), static_cast(mp_elem_number)); - // Extract the remaining digits from mp_float after the decimal point. + // Extract the remaining digits from cpp_float after the decimal point. str = boost::lexical_cast(data[0]); - // Extract all of the digits from mp_float, beginning with the first data element. + // Extract all of the digits from cpp_float, beginning with the first data element. for(std::size_t i = static_cast(1u); i < number_of_elements; i++) { std::stringstream ss; @@ -1714,7 +1714,7 @@ std::string mp_float::str(std::size_t number_of_digits, bool scientifi } template -bool mp_float::rd_string(const char* const s) +bool cpp_float::rd_string(const char* const s) { std::string str(s); @@ -1764,7 +1764,7 @@ bool mp_float::rd_string(const char* const s) } } - // Put the input string into the standard mp_float input form + // Put the input string into the standard cpp_float input form // aaa.bbbbE+/-n, where aa has 1...mp_elem_digits10, bbbb has an // even multiple of mp_elem_digits10 which are possibly zero padded // on the right-end, and n is a signed 32-bit integer which is an @@ -1892,7 +1892,7 @@ bool mp_float::rd_string(const char* const s) static_cast(pos_plus_one + max_dec)); } - // Now the input string has the standard mp_float input form. + // Now the input string has the standard cpp_float input form. // (See the comment above.) // Set all the data elements to 0. @@ -1916,7 +1916,7 @@ bool mp_float::rd_string(const char* const s) } // Check for overflow... - if(exp > mp_float_max_exp10) + if(exp > cpp_float_max_exp10) { const bool b_result_is_neg = neg; @@ -1926,12 +1926,12 @@ bool mp_float::rd_string(const char* const s) } // ...and check for underflow. - if(exp <= mp_float_min_exp10) + if(exp <= cpp_float_min_exp10) { - if(exp == mp_float_min_exp10) + if(exp == cpp_float_min_exp10) { // Check for identity with the minimum value. - mp_float test = *this; + cpp_float test = *this; test.exp = static_cast(0); @@ -1950,14 +1950,14 @@ bool mp_float::rd_string(const char* const s) } template -mp_float::mp_float(const double mantissa, const boost::int64_t exponent) +cpp_float::cpp_float(const double mantissa, const boost::int64_t exponent) : data (), exp (static_cast(0)), neg (false), fpclass (mp_finite), prec_elem(mp_elem_number) { - // Create an mp_float from mantissa and exponent. + // Create an cpp_float from mantissa and exponent. // This ctor does not maintain the full precision of double. const bool mantissa_is_iszero = (::fabs(mantissa) < ((std::numeric_limits::min)() * (1.0 + std::numeric_limits::epsilon()))); @@ -2002,7 +2002,7 @@ mp_float::mp_float(const double mantissa, const boost::int64_t exponen } template -mp_float& mp_float::operator = (long double a) +cpp_float& cpp_float::operator = (long double a) { // Christopher Kormanyos's original code used a cast to long long here, but that fails // when long double has more digits than a long long. @@ -2052,7 +2052,7 @@ mp_float& mp_float::operator = (long double a) } template -void mp_float::from_unsigned_long_long(const unsigned long long u) +void cpp_float::from_unsigned_long_long(const unsigned long long u) { std::fill(data.begin(), data.end(), static_cast(0u)); @@ -2084,7 +2084,7 @@ void mp_float::from_unsigned_long_long(const unsigned long long u) } template -void mp_float::mul_loop_uv(const boost::uint32_t* const u, const boost::uint32_t* const v, boost::uint32_t* const w, const boost::int32_t p) +void cpp_float::mul_loop_uv(const boost::uint32_t* const u, const boost::uint32_t* const v, boost::uint32_t* const w, const boost::int32_t p) { boost::uint64_t carry = static_cast(0u); @@ -2105,7 +2105,7 @@ void mp_float::mul_loop_uv(const boost::uint32_t* const u, const boost } template -boost::uint32_t mp_float::mul_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) +boost::uint32_t cpp_float::mul_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) { boost::uint64_t carry = static_cast(0u); @@ -2121,7 +2121,7 @@ boost::uint32_t mp_float::mul_loop_n(boost::uint32_t* const u, boost:: } template -boost::uint32_t mp_float::div_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) +boost::uint32_t cpp_float::div_loop_n(boost::uint32_t* const u, boost::uint32_t n, const boost::int32_t p) { boost::uint64_t prev = static_cast(0u); @@ -2136,269 +2136,269 @@ boost::uint32_t mp_float::div_loop_n(boost::uint32_t* const u, boost:: } template -mp_float mp_float::pow2(const boost::int64_t p) +cpp_float cpp_float::pow2(const boost::int64_t p) { // Create a static const table of p^2 for -128 < p < +128. // Note: The size of this table must be odd-numbered and // symmetric about 0. init.do_nothing(); - static const boost::array, 255u> p2_data = + static const boost::array, 255u> p2_data = {{ - mp_float("5.877471754111437539843682686111228389093327783860437607543758531392086297273635864257812500000000000e-39"), - mp_float("1.175494350822287507968736537222245677818665556772087521508751706278417259454727172851562500000000000e-38"), - mp_float("2.350988701644575015937473074444491355637331113544175043017503412556834518909454345703125000000000000e-38"), - mp_float("4.701977403289150031874946148888982711274662227088350086035006825113669037818908691406250000000000000e-38"), - mp_float("9.403954806578300063749892297777965422549324454176700172070013650227338075637817382812500000000000000e-38"), - mp_float("1.880790961315660012749978459555593084509864890835340034414002730045467615127563476562500000000000000e-37"), - mp_float("3.761581922631320025499956919111186169019729781670680068828005460090935230255126953125000000000000000e-37"), - mp_float("7.523163845262640050999913838222372338039459563341360137656010920181870460510253906250000000000000000e-37"), - mp_float("1.504632769052528010199982767644474467607891912668272027531202184036374092102050781250000000000000000e-36"), - mp_float("3.009265538105056020399965535288948935215783825336544055062404368072748184204101562500000000000000000e-36"), - mp_float("6.018531076210112040799931070577897870431567650673088110124808736145496368408203125000000000000000000e-36"), - mp_float("1.203706215242022408159986214115579574086313530134617622024961747229099273681640625000000000000000000e-35"), - mp_float("2.407412430484044816319972428231159148172627060269235244049923494458198547363281250000000000000000000e-35"), - mp_float("4.814824860968089632639944856462318296345254120538470488099846988916397094726562500000000000000000000e-35"), - mp_float("9.629649721936179265279889712924636592690508241076940976199693977832794189453125000000000000000000000e-35"), - mp_float("1.925929944387235853055977942584927318538101648215388195239938795566558837890625000000000000000000000e-34"), - mp_float("3.851859888774471706111955885169854637076203296430776390479877591133117675781250000000000000000000000e-34"), - mp_float("7.703719777548943412223911770339709274152406592861552780959755182266235351562500000000000000000000000e-34"), - mp_float("1.540743955509788682444782354067941854830481318572310556191951036453247070312500000000000000000000000e-33"), - mp_float("3.081487911019577364889564708135883709660962637144621112383902072906494140625000000000000000000000000e-33"), - mp_float("6.162975822039154729779129416271767419321925274289242224767804145812988281250000000000000000000000000e-33"), - mp_float("1.232595164407830945955825883254353483864385054857848444953560829162597656250000000000000000000000000e-32"), - mp_float("2.465190328815661891911651766508706967728770109715696889907121658325195312500000000000000000000000000e-32"), - mp_float("4.930380657631323783823303533017413935457540219431393779814243316650390625000000000000000000000000000e-32"), - mp_float("9.860761315262647567646607066034827870915080438862787559628486633300781250000000000000000000000000000e-32"), - mp_float("1.972152263052529513529321413206965574183016087772557511925697326660156250000000000000000000000000000e-31"), - mp_float("3.944304526105059027058642826413931148366032175545115023851394653320312500000000000000000000000000000e-31"), - mp_float("7.888609052210118054117285652827862296732064351090230047702789306640625000000000000000000000000000000e-31"), - mp_float("1.577721810442023610823457130565572459346412870218046009540557861328125000000000000000000000000000000e-30"), - mp_float("3.155443620884047221646914261131144918692825740436092019081115722656250000000000000000000000000000000e-30"), - mp_float("6.310887241768094443293828522262289837385651480872184038162231445312500000000000000000000000000000000e-30"), - mp_float("1.262177448353618888658765704452457967477130296174436807632446289062500000000000000000000000000000000e-29"), - mp_float("2.524354896707237777317531408904915934954260592348873615264892578125000000000000000000000000000000000e-29"), - mp_float("5.048709793414475554635062817809831869908521184697747230529785156250000000000000000000000000000000000e-29"), - mp_float("1.009741958682895110927012563561966373981704236939549446105957031250000000000000000000000000000000000e-28"), - mp_float("2.019483917365790221854025127123932747963408473879098892211914062500000000000000000000000000000000000e-28"), - mp_float("4.038967834731580443708050254247865495926816947758197784423828125000000000000000000000000000000000000e-28"), - mp_float("8.077935669463160887416100508495730991853633895516395568847656250000000000000000000000000000000000000e-28"), - mp_float("1.615587133892632177483220101699146198370726779103279113769531250000000000000000000000000000000000000e-27"), - mp_float("3.231174267785264354966440203398292396741453558206558227539062500000000000000000000000000000000000000e-27"), - mp_float("6.462348535570528709932880406796584793482907116413116455078125000000000000000000000000000000000000000e-27"), - mp_float("1.292469707114105741986576081359316958696581423282623291015625000000000000000000000000000000000000000e-26"), - mp_float("2.584939414228211483973152162718633917393162846565246582031250000000000000000000000000000000000000000e-26"), - mp_float("5.169878828456422967946304325437267834786325693130493164062500000000000000000000000000000000000000000e-26"), - mp_float("1.033975765691284593589260865087453566957265138626098632812500000000000000000000000000000000000000000e-25"), - mp_float("2.067951531382569187178521730174907133914530277252197265625000000000000000000000000000000000000000000e-25"), - mp_float("4.135903062765138374357043460349814267829060554504394531250000000000000000000000000000000000000000000e-25"), - mp_float("8.271806125530276748714086920699628535658121109008789062500000000000000000000000000000000000000000000e-25"), - mp_float("1.654361225106055349742817384139925707131624221801757812500000000000000000000000000000000000000000000e-24"), - mp_float("3.308722450212110699485634768279851414263248443603515625000000000000000000000000000000000000000000000e-24"), - mp_float("6.617444900424221398971269536559702828526496887207031250000000000000000000000000000000000000000000000e-24"), - mp_float("1.323488980084844279794253907311940565705299377441406250000000000000000000000000000000000000000000000e-23"), - mp_float("2.646977960169688559588507814623881131410598754882812500000000000000000000000000000000000000000000000e-23"), - mp_float("5.293955920339377119177015629247762262821197509765625000000000000000000000000000000000000000000000000e-23"), - mp_float("1.058791184067875423835403125849552452564239501953125000000000000000000000000000000000000000000000000e-22"), - mp_float("2.117582368135750847670806251699104905128479003906250000000000000000000000000000000000000000000000000e-22"), - mp_float("4.235164736271501695341612503398209810256958007812500000000000000000000000000000000000000000000000000e-22"), - mp_float("8.470329472543003390683225006796419620513916015625000000000000000000000000000000000000000000000000000e-22"), - mp_float("1.694065894508600678136645001359283924102783203125000000000000000000000000000000000000000000000000000e-21"), - mp_float("3.388131789017201356273290002718567848205566406250000000000000000000000000000000000000000000000000000e-21"), - mp_float("6.776263578034402712546580005437135696411132812500000000000000000000000000000000000000000000000000000e-21"), - mp_float("1.355252715606880542509316001087427139282226562500000000000000000000000000000000000000000000000000000e-20"), - mp_float("2.710505431213761085018632002174854278564453125000000000000000000000000000000000000000000000000000000e-20"), - mp_float("5.421010862427522170037264004349708557128906250000000000000000000000000000000000000000000000000000000e-20"), - mp_float("1.084202172485504434007452800869941711425781250000000000000000000000000000000000000000000000000000000e-19"), - mp_float("2.168404344971008868014905601739883422851562500000000000000000000000000000000000000000000000000000000e-19"), - mp_float("4.336808689942017736029811203479766845703125000000000000000000000000000000000000000000000000000000000e-19"), - mp_float("8.673617379884035472059622406959533691406250000000000000000000000000000000000000000000000000000000000e-19"), - mp_float("1.734723475976807094411924481391906738281250000000000000000000000000000000000000000000000000000000000e-18"), - mp_float("3.469446951953614188823848962783813476562500000000000000000000000000000000000000000000000000000000000e-18"), - mp_float("6.938893903907228377647697925567626953125000000000000000000000000000000000000000000000000000000000000e-18"), - mp_float("1.387778780781445675529539585113525390625000000000000000000000000000000000000000000000000000000000000e-17"), - mp_float("2.775557561562891351059079170227050781250000000000000000000000000000000000000000000000000000000000000e-17"), - mp_float("5.551115123125782702118158340454101562500000000000000000000000000000000000000000000000000000000000000e-17"), - mp_float("1.110223024625156540423631668090820312500000000000000000000000000000000000000000000000000000000000000e-16"), - mp_float("2.220446049250313080847263336181640625000000000000000000000000000000000000000000000000000000000000000e-16"), - mp_float("4.440892098500626161694526672363281250000000000000000000000000000000000000000000000000000000000000000e-16"), - mp_float("8.881784197001252323389053344726562500000000000000000000000000000000000000000000000000000000000000000e-16"), - mp_float("1.776356839400250464677810668945312500000000000000000000000000000000000000000000000000000000000000000e-15"), - mp_float("3.552713678800500929355621337890625000000000000000000000000000000000000000000000000000000000000000000e-15"), - mp_float("7.105427357601001858711242675781250000000000000000000000000000000000000000000000000000000000000000000e-15"), - mp_float("1.421085471520200371742248535156250000000000000000000000000000000000000000000000000000000000000000000e-14"), - mp_float("2.842170943040400743484497070312500000000000000000000000000000000000000000000000000000000000000000000e-14"), - mp_float("5.684341886080801486968994140625000000000000000000000000000000000000000000000000000000000000000000000e-14"), - mp_float("1.136868377216160297393798828125000000000000000000000000000000000000000000000000000000000000000000000e-13"), - mp_float("2.273736754432320594787597656250000000000000000000000000000000000000000000000000000000000000000000000e-13"), - mp_float("4.547473508864641189575195312500000000000000000000000000000000000000000000000000000000000000000000000e-13"), - mp_float("9.094947017729282379150390625000000000000000000000000000000000000000000000000000000000000000000000000e-13"), - mp_float("1.818989403545856475830078125000000000000000000000000000000000000000000000000000000000000000000000000e-12"), - mp_float("3.637978807091712951660156250000000000000000000000000000000000000000000000000000000000000000000000000e-12"), - mp_float("7.275957614183425903320312500000000000000000000000000000000000000000000000000000000000000000000000000e-12"), - mp_float("1.455191522836685180664062500000000000000000000000000000000000000000000000000000000000000000000000000e-11"), - mp_float("2.910383045673370361328125000000000000000000000000000000000000000000000000000000000000000000000000000e-11"), - mp_float("5.820766091346740722656250000000000000000000000000000000000000000000000000000000000000000000000000000e-11"), - mp_float("1.164153218269348144531250000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), - mp_float("2.328306436538696289062500000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), - mp_float("4.656612873077392578125000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), - mp_float("9.313225746154785156250000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), - mp_float("1.862645149230957031250000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), - mp_float("3.725290298461914062500000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), - mp_float("7.450580596923828125000000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), - mp_float("1.490116119384765625000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), - mp_float("2.980232238769531250000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), - mp_float("5.960464477539062500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), - mp_float("1.192092895507812500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), - mp_float("2.384185791015625000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), - mp_float("4.768371582031250000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), - mp_float("9.536743164062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), - mp_float("1.907348632812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), - mp_float("3.814697265625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), - mp_float("7.629394531250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), - mp_float("0.000015258789062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.000030517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.000061035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.000122070312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.000244140625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.000488281250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.000976562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.001953125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.003906250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.007812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.01562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.03125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.06250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), - mp_float("0.125"), - mp_float("0.25"), - mp_float("0.5"), + cpp_float("5.877471754111437539843682686111228389093327783860437607543758531392086297273635864257812500000000000e-39"), + cpp_float("1.175494350822287507968736537222245677818665556772087521508751706278417259454727172851562500000000000e-38"), + cpp_float("2.350988701644575015937473074444491355637331113544175043017503412556834518909454345703125000000000000e-38"), + cpp_float("4.701977403289150031874946148888982711274662227088350086035006825113669037818908691406250000000000000e-38"), + cpp_float("9.403954806578300063749892297777965422549324454176700172070013650227338075637817382812500000000000000e-38"), + cpp_float("1.880790961315660012749978459555593084509864890835340034414002730045467615127563476562500000000000000e-37"), + cpp_float("3.761581922631320025499956919111186169019729781670680068828005460090935230255126953125000000000000000e-37"), + cpp_float("7.523163845262640050999913838222372338039459563341360137656010920181870460510253906250000000000000000e-37"), + cpp_float("1.504632769052528010199982767644474467607891912668272027531202184036374092102050781250000000000000000e-36"), + cpp_float("3.009265538105056020399965535288948935215783825336544055062404368072748184204101562500000000000000000e-36"), + cpp_float("6.018531076210112040799931070577897870431567650673088110124808736145496368408203125000000000000000000e-36"), + cpp_float("1.203706215242022408159986214115579574086313530134617622024961747229099273681640625000000000000000000e-35"), + cpp_float("2.407412430484044816319972428231159148172627060269235244049923494458198547363281250000000000000000000e-35"), + cpp_float("4.814824860968089632639944856462318296345254120538470488099846988916397094726562500000000000000000000e-35"), + cpp_float("9.629649721936179265279889712924636592690508241076940976199693977832794189453125000000000000000000000e-35"), + cpp_float("1.925929944387235853055977942584927318538101648215388195239938795566558837890625000000000000000000000e-34"), + cpp_float("3.851859888774471706111955885169854637076203296430776390479877591133117675781250000000000000000000000e-34"), + cpp_float("7.703719777548943412223911770339709274152406592861552780959755182266235351562500000000000000000000000e-34"), + cpp_float("1.540743955509788682444782354067941854830481318572310556191951036453247070312500000000000000000000000e-33"), + cpp_float("3.081487911019577364889564708135883709660962637144621112383902072906494140625000000000000000000000000e-33"), + cpp_float("6.162975822039154729779129416271767419321925274289242224767804145812988281250000000000000000000000000e-33"), + cpp_float("1.232595164407830945955825883254353483864385054857848444953560829162597656250000000000000000000000000e-32"), + cpp_float("2.465190328815661891911651766508706967728770109715696889907121658325195312500000000000000000000000000e-32"), + cpp_float("4.930380657631323783823303533017413935457540219431393779814243316650390625000000000000000000000000000e-32"), + cpp_float("9.860761315262647567646607066034827870915080438862787559628486633300781250000000000000000000000000000e-32"), + cpp_float("1.972152263052529513529321413206965574183016087772557511925697326660156250000000000000000000000000000e-31"), + cpp_float("3.944304526105059027058642826413931148366032175545115023851394653320312500000000000000000000000000000e-31"), + cpp_float("7.888609052210118054117285652827862296732064351090230047702789306640625000000000000000000000000000000e-31"), + cpp_float("1.577721810442023610823457130565572459346412870218046009540557861328125000000000000000000000000000000e-30"), + cpp_float("3.155443620884047221646914261131144918692825740436092019081115722656250000000000000000000000000000000e-30"), + cpp_float("6.310887241768094443293828522262289837385651480872184038162231445312500000000000000000000000000000000e-30"), + cpp_float("1.262177448353618888658765704452457967477130296174436807632446289062500000000000000000000000000000000e-29"), + cpp_float("2.524354896707237777317531408904915934954260592348873615264892578125000000000000000000000000000000000e-29"), + cpp_float("5.048709793414475554635062817809831869908521184697747230529785156250000000000000000000000000000000000e-29"), + cpp_float("1.009741958682895110927012563561966373981704236939549446105957031250000000000000000000000000000000000e-28"), + cpp_float("2.019483917365790221854025127123932747963408473879098892211914062500000000000000000000000000000000000e-28"), + cpp_float("4.038967834731580443708050254247865495926816947758197784423828125000000000000000000000000000000000000e-28"), + cpp_float("8.077935669463160887416100508495730991853633895516395568847656250000000000000000000000000000000000000e-28"), + cpp_float("1.615587133892632177483220101699146198370726779103279113769531250000000000000000000000000000000000000e-27"), + cpp_float("3.231174267785264354966440203398292396741453558206558227539062500000000000000000000000000000000000000e-27"), + cpp_float("6.462348535570528709932880406796584793482907116413116455078125000000000000000000000000000000000000000e-27"), + cpp_float("1.292469707114105741986576081359316958696581423282623291015625000000000000000000000000000000000000000e-26"), + cpp_float("2.584939414228211483973152162718633917393162846565246582031250000000000000000000000000000000000000000e-26"), + cpp_float("5.169878828456422967946304325437267834786325693130493164062500000000000000000000000000000000000000000e-26"), + cpp_float("1.033975765691284593589260865087453566957265138626098632812500000000000000000000000000000000000000000e-25"), + cpp_float("2.067951531382569187178521730174907133914530277252197265625000000000000000000000000000000000000000000e-25"), + cpp_float("4.135903062765138374357043460349814267829060554504394531250000000000000000000000000000000000000000000e-25"), + cpp_float("8.271806125530276748714086920699628535658121109008789062500000000000000000000000000000000000000000000e-25"), + cpp_float("1.654361225106055349742817384139925707131624221801757812500000000000000000000000000000000000000000000e-24"), + cpp_float("3.308722450212110699485634768279851414263248443603515625000000000000000000000000000000000000000000000e-24"), + cpp_float("6.617444900424221398971269536559702828526496887207031250000000000000000000000000000000000000000000000e-24"), + cpp_float("1.323488980084844279794253907311940565705299377441406250000000000000000000000000000000000000000000000e-23"), + cpp_float("2.646977960169688559588507814623881131410598754882812500000000000000000000000000000000000000000000000e-23"), + cpp_float("5.293955920339377119177015629247762262821197509765625000000000000000000000000000000000000000000000000e-23"), + cpp_float("1.058791184067875423835403125849552452564239501953125000000000000000000000000000000000000000000000000e-22"), + cpp_float("2.117582368135750847670806251699104905128479003906250000000000000000000000000000000000000000000000000e-22"), + cpp_float("4.235164736271501695341612503398209810256958007812500000000000000000000000000000000000000000000000000e-22"), + cpp_float("8.470329472543003390683225006796419620513916015625000000000000000000000000000000000000000000000000000e-22"), + cpp_float("1.694065894508600678136645001359283924102783203125000000000000000000000000000000000000000000000000000e-21"), + cpp_float("3.388131789017201356273290002718567848205566406250000000000000000000000000000000000000000000000000000e-21"), + cpp_float("6.776263578034402712546580005437135696411132812500000000000000000000000000000000000000000000000000000e-21"), + cpp_float("1.355252715606880542509316001087427139282226562500000000000000000000000000000000000000000000000000000e-20"), + cpp_float("2.710505431213761085018632002174854278564453125000000000000000000000000000000000000000000000000000000e-20"), + cpp_float("5.421010862427522170037264004349708557128906250000000000000000000000000000000000000000000000000000000e-20"), + cpp_float("1.084202172485504434007452800869941711425781250000000000000000000000000000000000000000000000000000000e-19"), + cpp_float("2.168404344971008868014905601739883422851562500000000000000000000000000000000000000000000000000000000e-19"), + cpp_float("4.336808689942017736029811203479766845703125000000000000000000000000000000000000000000000000000000000e-19"), + cpp_float("8.673617379884035472059622406959533691406250000000000000000000000000000000000000000000000000000000000e-19"), + cpp_float("1.734723475976807094411924481391906738281250000000000000000000000000000000000000000000000000000000000e-18"), + cpp_float("3.469446951953614188823848962783813476562500000000000000000000000000000000000000000000000000000000000e-18"), + cpp_float("6.938893903907228377647697925567626953125000000000000000000000000000000000000000000000000000000000000e-18"), + cpp_float("1.387778780781445675529539585113525390625000000000000000000000000000000000000000000000000000000000000e-17"), + cpp_float("2.775557561562891351059079170227050781250000000000000000000000000000000000000000000000000000000000000e-17"), + cpp_float("5.551115123125782702118158340454101562500000000000000000000000000000000000000000000000000000000000000e-17"), + cpp_float("1.110223024625156540423631668090820312500000000000000000000000000000000000000000000000000000000000000e-16"), + cpp_float("2.220446049250313080847263336181640625000000000000000000000000000000000000000000000000000000000000000e-16"), + cpp_float("4.440892098500626161694526672363281250000000000000000000000000000000000000000000000000000000000000000e-16"), + cpp_float("8.881784197001252323389053344726562500000000000000000000000000000000000000000000000000000000000000000e-16"), + cpp_float("1.776356839400250464677810668945312500000000000000000000000000000000000000000000000000000000000000000e-15"), + cpp_float("3.552713678800500929355621337890625000000000000000000000000000000000000000000000000000000000000000000e-15"), + cpp_float("7.105427357601001858711242675781250000000000000000000000000000000000000000000000000000000000000000000e-15"), + cpp_float("1.421085471520200371742248535156250000000000000000000000000000000000000000000000000000000000000000000e-14"), + cpp_float("2.842170943040400743484497070312500000000000000000000000000000000000000000000000000000000000000000000e-14"), + cpp_float("5.684341886080801486968994140625000000000000000000000000000000000000000000000000000000000000000000000e-14"), + cpp_float("1.136868377216160297393798828125000000000000000000000000000000000000000000000000000000000000000000000e-13"), + cpp_float("2.273736754432320594787597656250000000000000000000000000000000000000000000000000000000000000000000000e-13"), + cpp_float("4.547473508864641189575195312500000000000000000000000000000000000000000000000000000000000000000000000e-13"), + cpp_float("9.094947017729282379150390625000000000000000000000000000000000000000000000000000000000000000000000000e-13"), + cpp_float("1.818989403545856475830078125000000000000000000000000000000000000000000000000000000000000000000000000e-12"), + cpp_float("3.637978807091712951660156250000000000000000000000000000000000000000000000000000000000000000000000000e-12"), + cpp_float("7.275957614183425903320312500000000000000000000000000000000000000000000000000000000000000000000000000e-12"), + cpp_float("1.455191522836685180664062500000000000000000000000000000000000000000000000000000000000000000000000000e-11"), + cpp_float("2.910383045673370361328125000000000000000000000000000000000000000000000000000000000000000000000000000e-11"), + cpp_float("5.820766091346740722656250000000000000000000000000000000000000000000000000000000000000000000000000000e-11"), + cpp_float("1.164153218269348144531250000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), + cpp_float("2.328306436538696289062500000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), + cpp_float("4.656612873077392578125000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), + cpp_float("9.313225746154785156250000000000000000000000000000000000000000000000000000000000000000000000000000000e-10"), + cpp_float("1.862645149230957031250000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), + cpp_float("3.725290298461914062500000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), + cpp_float("7.450580596923828125000000000000000000000000000000000000000000000000000000000000000000000000000000000e-9"), + cpp_float("1.490116119384765625000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), + cpp_float("2.980232238769531250000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), + cpp_float("5.960464477539062500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-8"), + cpp_float("1.192092895507812500000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), + cpp_float("2.384185791015625000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), + cpp_float("4.768371582031250000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), + cpp_float("9.536743164062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-7"), + cpp_float("1.907348632812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), + cpp_float("3.814697265625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), + cpp_float("7.629394531250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e-6"), + cpp_float("0.000015258789062500000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000030517578125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000061035156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000122070312500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000244140625000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000488281250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.000976562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.001953125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.003906250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.007812500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.01562500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.03125000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.06250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), + cpp_float("0.125"), + cpp_float("0.25"), + cpp_float("0.5"), one(), two(), - mp_float(static_cast(4)), - mp_float(static_cast(8)), - mp_float(static_cast(16)), - mp_float(static_cast(32)), - mp_float(static_cast(64)), - mp_float(static_cast(128)), - mp_float(static_cast(256)), - mp_float(static_cast(512)), - mp_float(static_cast(1024)), - mp_float(static_cast(2048)), - mp_float(static_cast(4096)), - mp_float(static_cast(8192)), - mp_float(static_cast(16384)), - mp_float(static_cast(32768)), - mp_float(static_cast(65536)), - mp_float(static_cast(131072)), - mp_float(static_cast(262144)), - mp_float(static_cast(524288)), - mp_float(static_cast(1uL << 20u)), - mp_float(static_cast(1uL << 21u)), - mp_float(static_cast(1uL << 22u)), - mp_float(static_cast(1uL << 23u)), - mp_float(static_cast(1uL << 24u)), - mp_float(static_cast(1uL << 25u)), - mp_float(static_cast(1uL << 26u)), - mp_float(static_cast(1uL << 27u)), - mp_float(static_cast(1uL << 28u)), - mp_float(static_cast(1uL << 29u)), - mp_float(static_cast(1uL << 30u)), - mp_float(static_cast(1uL << 31u)), - mp_float(static_cast(1uLL << 32u)), - mp_float(static_cast(1uLL << 33u)), - mp_float(static_cast(1uLL << 34u)), - mp_float(static_cast(1uLL << 35u)), - mp_float(static_cast(1uLL << 36u)), - mp_float(static_cast(1uLL << 37u)), - mp_float(static_cast(1uLL << 38u)), - mp_float(static_cast(1uLL << 39u)), - mp_float(static_cast(1uLL << 40u)), - mp_float(static_cast(1uLL << 41u)), - mp_float(static_cast(1uLL << 42u)), - mp_float(static_cast(1uLL << 43u)), - mp_float(static_cast(1uLL << 44u)), - mp_float(static_cast(1uLL << 45u)), - mp_float(static_cast(1uLL << 46u)), - mp_float(static_cast(1uLL << 47u)), - mp_float(static_cast(1uLL << 48u)), - mp_float(static_cast(1uLL << 49u)), - mp_float(static_cast(1uLL << 50u)), - mp_float(static_cast(1uLL << 51u)), - mp_float(static_cast(1uLL << 52u)), - mp_float(static_cast(1uLL << 53u)), - mp_float(static_cast(1uLL << 54u)), - mp_float(static_cast(1uLL << 55u)), - mp_float(static_cast(1uLL << 56u)), - mp_float(static_cast(1uLL << 57u)), - mp_float(static_cast(1uLL << 58u)), - mp_float(static_cast(1uLL << 59u)), - mp_float(static_cast(1uLL << 60u)), - mp_float(static_cast(1uLL << 61u)), - mp_float(static_cast(1uLL << 62u)), - mp_float(static_cast(1uLL << 63u)), - mp_float("1.844674407370955161600000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), - mp_float("3.689348814741910323200000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), - mp_float("7.378697629483820646400000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), - mp_float("1.475739525896764129280000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), - mp_float("2.951479051793528258560000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), - mp_float("5.902958103587056517120000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), - mp_float("1.180591620717411303424000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), - mp_float("2.361183241434822606848000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), - mp_float("4.722366482869645213696000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), - mp_float("9.444732965739290427392000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), - mp_float("1.888946593147858085478400000000000000000000000000000000000000000000000000000000000000000000000000000e22"), - mp_float("3.777893186295716170956800000000000000000000000000000000000000000000000000000000000000000000000000000e22"), - mp_float("7.555786372591432341913600000000000000000000000000000000000000000000000000000000000000000000000000000e22"), - mp_float("1.511157274518286468382720000000000000000000000000000000000000000000000000000000000000000000000000000e23"), - mp_float("3.022314549036572936765440000000000000000000000000000000000000000000000000000000000000000000000000000e23"), - mp_float("6.044629098073145873530880000000000000000000000000000000000000000000000000000000000000000000000000000e23"), - mp_float("1.208925819614629174706176000000000000000000000000000000000000000000000000000000000000000000000000000e24"), - mp_float("2.417851639229258349412352000000000000000000000000000000000000000000000000000000000000000000000000000e24"), - mp_float("4.835703278458516698824704000000000000000000000000000000000000000000000000000000000000000000000000000e24"), - mp_float("9.671406556917033397649408000000000000000000000000000000000000000000000000000000000000000000000000000e24"), - mp_float("1.934281311383406679529881600000000000000000000000000000000000000000000000000000000000000000000000000e25"), - mp_float("3.868562622766813359059763200000000000000000000000000000000000000000000000000000000000000000000000000e25"), - mp_float("7.737125245533626718119526400000000000000000000000000000000000000000000000000000000000000000000000000e25"), - mp_float("1.547425049106725343623905280000000000000000000000000000000000000000000000000000000000000000000000000e26"), - mp_float("3.094850098213450687247810560000000000000000000000000000000000000000000000000000000000000000000000000e26"), - mp_float("6.189700196426901374495621120000000000000000000000000000000000000000000000000000000000000000000000000e26"), - mp_float("1.237940039285380274899124224000000000000000000000000000000000000000000000000000000000000000000000000e27"), - mp_float("2.475880078570760549798248448000000000000000000000000000000000000000000000000000000000000000000000000e27"), - mp_float("4.951760157141521099596496896000000000000000000000000000000000000000000000000000000000000000000000000e27"), - mp_float("9.903520314283042199192993792000000000000000000000000000000000000000000000000000000000000000000000000e27"), - mp_float("1.980704062856608439838598758400000000000000000000000000000000000000000000000000000000000000000000000e28"), - mp_float("3.961408125713216879677197516800000000000000000000000000000000000000000000000000000000000000000000000e28"), - mp_float("7.922816251426433759354395033600000000000000000000000000000000000000000000000000000000000000000000000e28"), - mp_float("1.584563250285286751870879006720000000000000000000000000000000000000000000000000000000000000000000000e29"), - mp_float("3.169126500570573503741758013440000000000000000000000000000000000000000000000000000000000000000000000e29"), - mp_float("6.338253001141147007483516026880000000000000000000000000000000000000000000000000000000000000000000000e29"), - mp_float("1.267650600228229401496703205376000000000000000000000000000000000000000000000000000000000000000000000e30"), - mp_float("2.535301200456458802993406410752000000000000000000000000000000000000000000000000000000000000000000000e30"), - mp_float("5.070602400912917605986812821504000000000000000000000000000000000000000000000000000000000000000000000e30"), - mp_float("1.014120480182583521197362564300800000000000000000000000000000000000000000000000000000000000000000000e31"), - mp_float("2.028240960365167042394725128601600000000000000000000000000000000000000000000000000000000000000000000e31"), - mp_float("4.056481920730334084789450257203200000000000000000000000000000000000000000000000000000000000000000000e31"), - mp_float("8.112963841460668169578900514406400000000000000000000000000000000000000000000000000000000000000000000e31"), - mp_float("1.622592768292133633915780102881280000000000000000000000000000000000000000000000000000000000000000000e32"), - mp_float("3.245185536584267267831560205762560000000000000000000000000000000000000000000000000000000000000000000e32"), - mp_float("6.490371073168534535663120411525120000000000000000000000000000000000000000000000000000000000000000000e32"), - mp_float("1.298074214633706907132624082305024000000000000000000000000000000000000000000000000000000000000000000e33"), - mp_float("2.596148429267413814265248164610048000000000000000000000000000000000000000000000000000000000000000000e33"), - mp_float("5.192296858534827628530496329220096000000000000000000000000000000000000000000000000000000000000000000e33"), - mp_float("1.038459371706965525706099265844019200000000000000000000000000000000000000000000000000000000000000000e34"), - mp_float("2.076918743413931051412198531688038400000000000000000000000000000000000000000000000000000000000000000e34"), - mp_float("4.153837486827862102824397063376076800000000000000000000000000000000000000000000000000000000000000000e34"), - mp_float("8.307674973655724205648794126752153600000000000000000000000000000000000000000000000000000000000000000e34"), - mp_float("1.661534994731144841129758825350430720000000000000000000000000000000000000000000000000000000000000000e35"), - mp_float("3.323069989462289682259517650700861440000000000000000000000000000000000000000000000000000000000000000e35"), - mp_float("6.646139978924579364519035301401722880000000000000000000000000000000000000000000000000000000000000000e35"), - mp_float("1.329227995784915872903807060280344576000000000000000000000000000000000000000000000000000000000000000e36"), - mp_float("2.658455991569831745807614120560689152000000000000000000000000000000000000000000000000000000000000000e36"), - mp_float("5.316911983139663491615228241121378304000000000000000000000000000000000000000000000000000000000000000e36"), - mp_float("1.063382396627932698323045648224275660800000000000000000000000000000000000000000000000000000000000000e37"), - mp_float("2.126764793255865396646091296448551321600000000000000000000000000000000000000000000000000000000000000e37"), - mp_float("4.253529586511730793292182592897102643200000000000000000000000000000000000000000000000000000000000000e37"), - mp_float("8.507059173023461586584365185794205286400000000000000000000000000000000000000000000000000000000000000e37"), - mp_float("1.701411834604692317316873037158841057280000000000000000000000000000000000000000000000000000000000000e38") + cpp_float(static_cast(4)), + cpp_float(static_cast(8)), + cpp_float(static_cast(16)), + cpp_float(static_cast(32)), + cpp_float(static_cast(64)), + cpp_float(static_cast(128)), + cpp_float(static_cast(256)), + cpp_float(static_cast(512)), + cpp_float(static_cast(1024)), + cpp_float(static_cast(2048)), + cpp_float(static_cast(4096)), + cpp_float(static_cast(8192)), + cpp_float(static_cast(16384)), + cpp_float(static_cast(32768)), + cpp_float(static_cast(65536)), + cpp_float(static_cast(131072)), + cpp_float(static_cast(262144)), + cpp_float(static_cast(524288)), + cpp_float(static_cast(1uL << 20u)), + cpp_float(static_cast(1uL << 21u)), + cpp_float(static_cast(1uL << 22u)), + cpp_float(static_cast(1uL << 23u)), + cpp_float(static_cast(1uL << 24u)), + cpp_float(static_cast(1uL << 25u)), + cpp_float(static_cast(1uL << 26u)), + cpp_float(static_cast(1uL << 27u)), + cpp_float(static_cast(1uL << 28u)), + cpp_float(static_cast(1uL << 29u)), + cpp_float(static_cast(1uL << 30u)), + cpp_float(static_cast(1uL << 31u)), + cpp_float(static_cast(1uLL << 32u)), + cpp_float(static_cast(1uLL << 33u)), + cpp_float(static_cast(1uLL << 34u)), + cpp_float(static_cast(1uLL << 35u)), + cpp_float(static_cast(1uLL << 36u)), + cpp_float(static_cast(1uLL << 37u)), + cpp_float(static_cast(1uLL << 38u)), + cpp_float(static_cast(1uLL << 39u)), + cpp_float(static_cast(1uLL << 40u)), + cpp_float(static_cast(1uLL << 41u)), + cpp_float(static_cast(1uLL << 42u)), + cpp_float(static_cast(1uLL << 43u)), + cpp_float(static_cast(1uLL << 44u)), + cpp_float(static_cast(1uLL << 45u)), + cpp_float(static_cast(1uLL << 46u)), + cpp_float(static_cast(1uLL << 47u)), + cpp_float(static_cast(1uLL << 48u)), + cpp_float(static_cast(1uLL << 49u)), + cpp_float(static_cast(1uLL << 50u)), + cpp_float(static_cast(1uLL << 51u)), + cpp_float(static_cast(1uLL << 52u)), + cpp_float(static_cast(1uLL << 53u)), + cpp_float(static_cast(1uLL << 54u)), + cpp_float(static_cast(1uLL << 55u)), + cpp_float(static_cast(1uLL << 56u)), + cpp_float(static_cast(1uLL << 57u)), + cpp_float(static_cast(1uLL << 58u)), + cpp_float(static_cast(1uLL << 59u)), + cpp_float(static_cast(1uLL << 60u)), + cpp_float(static_cast(1uLL << 61u)), + cpp_float(static_cast(1uLL << 62u)), + cpp_float(static_cast(1uLL << 63u)), + cpp_float("1.844674407370955161600000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), + cpp_float("3.689348814741910323200000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), + cpp_float("7.378697629483820646400000000000000000000000000000000000000000000000000000000000000000000000000000000e19"), + cpp_float("1.475739525896764129280000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), + cpp_float("2.951479051793528258560000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), + cpp_float("5.902958103587056517120000000000000000000000000000000000000000000000000000000000000000000000000000000e20"), + cpp_float("1.180591620717411303424000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), + cpp_float("2.361183241434822606848000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), + cpp_float("4.722366482869645213696000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), + cpp_float("9.444732965739290427392000000000000000000000000000000000000000000000000000000000000000000000000000000e21"), + cpp_float("1.888946593147858085478400000000000000000000000000000000000000000000000000000000000000000000000000000e22"), + cpp_float("3.777893186295716170956800000000000000000000000000000000000000000000000000000000000000000000000000000e22"), + cpp_float("7.555786372591432341913600000000000000000000000000000000000000000000000000000000000000000000000000000e22"), + cpp_float("1.511157274518286468382720000000000000000000000000000000000000000000000000000000000000000000000000000e23"), + cpp_float("3.022314549036572936765440000000000000000000000000000000000000000000000000000000000000000000000000000e23"), + cpp_float("6.044629098073145873530880000000000000000000000000000000000000000000000000000000000000000000000000000e23"), + cpp_float("1.208925819614629174706176000000000000000000000000000000000000000000000000000000000000000000000000000e24"), + cpp_float("2.417851639229258349412352000000000000000000000000000000000000000000000000000000000000000000000000000e24"), + cpp_float("4.835703278458516698824704000000000000000000000000000000000000000000000000000000000000000000000000000e24"), + cpp_float("9.671406556917033397649408000000000000000000000000000000000000000000000000000000000000000000000000000e24"), + cpp_float("1.934281311383406679529881600000000000000000000000000000000000000000000000000000000000000000000000000e25"), + cpp_float("3.868562622766813359059763200000000000000000000000000000000000000000000000000000000000000000000000000e25"), + cpp_float("7.737125245533626718119526400000000000000000000000000000000000000000000000000000000000000000000000000e25"), + cpp_float("1.547425049106725343623905280000000000000000000000000000000000000000000000000000000000000000000000000e26"), + cpp_float("3.094850098213450687247810560000000000000000000000000000000000000000000000000000000000000000000000000e26"), + cpp_float("6.189700196426901374495621120000000000000000000000000000000000000000000000000000000000000000000000000e26"), + cpp_float("1.237940039285380274899124224000000000000000000000000000000000000000000000000000000000000000000000000e27"), + cpp_float("2.475880078570760549798248448000000000000000000000000000000000000000000000000000000000000000000000000e27"), + cpp_float("4.951760157141521099596496896000000000000000000000000000000000000000000000000000000000000000000000000e27"), + cpp_float("9.903520314283042199192993792000000000000000000000000000000000000000000000000000000000000000000000000e27"), + cpp_float("1.980704062856608439838598758400000000000000000000000000000000000000000000000000000000000000000000000e28"), + cpp_float("3.961408125713216879677197516800000000000000000000000000000000000000000000000000000000000000000000000e28"), + cpp_float("7.922816251426433759354395033600000000000000000000000000000000000000000000000000000000000000000000000e28"), + cpp_float("1.584563250285286751870879006720000000000000000000000000000000000000000000000000000000000000000000000e29"), + cpp_float("3.169126500570573503741758013440000000000000000000000000000000000000000000000000000000000000000000000e29"), + cpp_float("6.338253001141147007483516026880000000000000000000000000000000000000000000000000000000000000000000000e29"), + cpp_float("1.267650600228229401496703205376000000000000000000000000000000000000000000000000000000000000000000000e30"), + cpp_float("2.535301200456458802993406410752000000000000000000000000000000000000000000000000000000000000000000000e30"), + cpp_float("5.070602400912917605986812821504000000000000000000000000000000000000000000000000000000000000000000000e30"), + cpp_float("1.014120480182583521197362564300800000000000000000000000000000000000000000000000000000000000000000000e31"), + cpp_float("2.028240960365167042394725128601600000000000000000000000000000000000000000000000000000000000000000000e31"), + cpp_float("4.056481920730334084789450257203200000000000000000000000000000000000000000000000000000000000000000000e31"), + cpp_float("8.112963841460668169578900514406400000000000000000000000000000000000000000000000000000000000000000000e31"), + cpp_float("1.622592768292133633915780102881280000000000000000000000000000000000000000000000000000000000000000000e32"), + cpp_float("3.245185536584267267831560205762560000000000000000000000000000000000000000000000000000000000000000000e32"), + cpp_float("6.490371073168534535663120411525120000000000000000000000000000000000000000000000000000000000000000000e32"), + cpp_float("1.298074214633706907132624082305024000000000000000000000000000000000000000000000000000000000000000000e33"), + cpp_float("2.596148429267413814265248164610048000000000000000000000000000000000000000000000000000000000000000000e33"), + cpp_float("5.192296858534827628530496329220096000000000000000000000000000000000000000000000000000000000000000000e33"), + cpp_float("1.038459371706965525706099265844019200000000000000000000000000000000000000000000000000000000000000000e34"), + cpp_float("2.076918743413931051412198531688038400000000000000000000000000000000000000000000000000000000000000000e34"), + cpp_float("4.153837486827862102824397063376076800000000000000000000000000000000000000000000000000000000000000000e34"), + cpp_float("8.307674973655724205648794126752153600000000000000000000000000000000000000000000000000000000000000000e34"), + cpp_float("1.661534994731144841129758825350430720000000000000000000000000000000000000000000000000000000000000000e35"), + cpp_float("3.323069989462289682259517650700861440000000000000000000000000000000000000000000000000000000000000000e35"), + cpp_float("6.646139978924579364519035301401722880000000000000000000000000000000000000000000000000000000000000000e35"), + cpp_float("1.329227995784915872903807060280344576000000000000000000000000000000000000000000000000000000000000000e36"), + cpp_float("2.658455991569831745807614120560689152000000000000000000000000000000000000000000000000000000000000000e36"), + cpp_float("5.316911983139663491615228241121378304000000000000000000000000000000000000000000000000000000000000000e36"), + cpp_float("1.063382396627932698323045648224275660800000000000000000000000000000000000000000000000000000000000000e37"), + cpp_float("2.126764793255865396646091296448551321600000000000000000000000000000000000000000000000000000000000000e37"), + cpp_float("4.253529586511730793292182592897102643200000000000000000000000000000000000000000000000000000000000000e37"), + cpp_float("8.507059173023461586584365185794205286400000000000000000000000000000000000000000000000000000000000000e37"), + cpp_float("1.701411834604692317316873037158841057280000000000000000000000000000000000000000000000000000000000000e38") }}; if((p > static_cast(-128)) && (p < static_cast(+128))) @@ -2414,11 +2414,11 @@ mp_float mp_float::pow2(const boost::int64_t p) else if(p < static_cast(std::numeric_limits::digits)) { const boost::uint64_t p2 = static_cast(static_cast(1uLL) << p); - return mp_float(p2); + return cpp_float(p2); } else { - mp_float t; + cpp_float t; default_ops::detail::pow_imp(t, two(), p, mpl::true_()); return t; } @@ -2426,49 +2426,49 @@ mp_float mp_float::pow2(const boost::int64_t p) template -inline void add(mp_float& result, const mp_float& o) +inline void add(cpp_float& result, const cpp_float& o) { result += o; } template -inline void subtract(mp_float& result, const mp_float& o) +inline void subtract(cpp_float& result, const cpp_float& o) { result -= o; } template -inline void multiply(mp_float& result, const mp_float& o) +inline void multiply(cpp_float& result, const cpp_float& o) { result *= o; } template -inline void divide(mp_float& result, const mp_float& o) +inline void divide(cpp_float& result, const cpp_float& o) { result /= o; } template -inline void add(mp_float& result, const unsigned long long& o) +inline void add(cpp_float& result, const unsigned long long& o) { result.add_unsigned_long_long(o); } template -inline void subtract(mp_float& result, const unsigned long long& o) +inline void subtract(cpp_float& result, const unsigned long long& o) { result.sub_unsigned_long_long(o); } template -inline void multiply(mp_float& result, const unsigned long long& o) +inline void multiply(cpp_float& result, const unsigned long long& o) { result.mul_unsigned_long_long(o); } template -inline void divide(mp_float& result, const unsigned long long& o) +inline void divide(cpp_float& result, const unsigned long long& o) { result.div_unsigned_long_long(o); } template -inline void add(mp_float& result, long long o) +inline void add(cpp_float& result, long long o) { if(o < 0) result.sub_unsigned_long_long(-o); @@ -2476,7 +2476,7 @@ inline void add(mp_float& result, long long o) result.add_unsigned_long_long(o); } template -inline void subtract(mp_float& result, long long o) +inline void subtract(cpp_float& result, long long o) { if(o < 0) result.add_unsigned_long_long(-o); @@ -2484,7 +2484,7 @@ inline void subtract(mp_float& result, long long o) result.sub_unsigned_long_long(o); } template -inline void multiply(mp_float& result, long long o) +inline void multiply(cpp_float& result, long long o) { if(o < 0) { @@ -2495,7 +2495,7 @@ inline void multiply(mp_float& result, long long o) result.mul_unsigned_long_long(o); } template -inline void divide(mp_float& result, long long o) +inline void divide(cpp_float& result, long long o) { if(o < 0) { @@ -2507,17 +2507,17 @@ inline void divide(mp_float& result, long long o) } template -inline void convert_to(unsigned long long* result, const mp_float& val) +inline void convert_to(unsigned long long* result, const cpp_float& val) { *result = val.extract_unsigned_long_long(); } template -inline void convert_to(long long* result, const mp_float& val) +inline void convert_to(long long* result, const cpp_float& val) { *result = val.extract_signed_long_long(); } template -inline void convert_to(long double* result, mp_float& val) +inline void convert_to(long double* result, cpp_float& val) { *result = val.extract_long_double(); } @@ -2526,7 +2526,7 @@ inline void convert_to(long double* result, mp_float& val) // Non member function support: // template -inline int eval_fpclassify(const mp_float& x) +inline int eval_fpclassify(const cpp_float& x) { if(x.isinf()) return FP_INFINITE; @@ -2538,7 +2538,7 @@ inline int eval_fpclassify(const mp_float& x) } template -inline void eval_abs(mp_float& result, const mp_float& x) +inline void eval_abs(cpp_float& result, const cpp_float& x) { result = x; if(x.isneg()) @@ -2546,7 +2546,7 @@ inline void eval_abs(mp_float& result, const mp_float& x) } template -inline void eval_fabs(mp_float& result, const mp_float& x) +inline void eval_fabs(cpp_float& result, const cpp_float& x) { result = x; if(x.isneg()) @@ -2554,14 +2554,14 @@ inline void eval_fabs(mp_float& result, const mp_float& x) } template -inline void eval_sqrt(mp_float& result, const mp_float& x) +inline void eval_sqrt(cpp_float& result, const cpp_float& x) { result = x; result.calculate_sqrt(); } template -inline void eval_floor(mp_float& result, const mp_float& x) +inline void eval_floor(cpp_float& result, const cpp_float& x) { result = x; if(!x.isfinite() || x.isint()) @@ -2570,12 +2570,12 @@ inline void eval_floor(mp_float& result, const mp_float& x) } if(x.isneg()) - result -= mp_float::one(); + result -= cpp_float::one(); result = result.extract_integer_part(); } template -inline void eval_ceil(mp_float& result, const mp_float& x) +inline void eval_ceil(cpp_float& result, const cpp_float& x) { result = x; if(!x.isfinite() || x.isint()) @@ -2584,16 +2584,16 @@ inline void eval_ceil(mp_float& result, const mp_float& x) } if(!x.isneg()) - result += mp_float::one(); + result += cpp_float::one(); result = result.extract_integer_part(); } template -inline void eval_trunc(mp_float& result, const mp_float& x) +inline void eval_trunc(cpp_float& result, const cpp_float& x) { if(!x.isfinite()) { - result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, mp_number >(x), 0, boost::math::policies::policy<>()).backend(); + result = boost::math::policies::raise_rounding_error("boost::multiprecision::trunc<%1%>(%1%)", 0, mp_number >(x), 0, boost::math::policies::policy<>()).backend(); return; } else if(x.isint()) @@ -2605,14 +2605,14 @@ inline void eval_trunc(mp_float& result, const mp_float& x) } template -inline void eval_ldexp(mp_float& result, const mp_float& x, long long e) +inline void eval_ldexp(cpp_float& result, const cpp_float& x, long long e) { result = x; - result *= mp_float::pow2(e); + result *= cpp_float::pow2(e); } template -inline void eval_frexp(mp_float& result, const mp_float& x, long long* e) +inline void eval_frexp(cpp_float& result, const cpp_float& x, long long* e) { result = x; if(result.isneg()) @@ -2624,16 +2624,16 @@ inline void eval_frexp(mp_float& result, const mp_float& x, throw std::runtime_error("Exponent is too large to be represented as a power of 2."); t *= 3; - result *= mp_float::pow2(-t); + result *= cpp_float::pow2(-t); - while(result.compare(mp_float::one()) >= 0) + while(result.compare(cpp_float::one()) >= 0) { - result /= mp_float::two(); + result /= cpp_float::two(); ++t; } - while(result.compare(mp_float::half()) < 0) + while(result.compare(cpp_float::half()) < 0) { - result *= mp_float::two(); + result *= cpp_float::two(); --t; } *e = t; @@ -2642,7 +2642,7 @@ inline void eval_frexp(mp_float& result, const mp_float& x, } template -inline void eval_frexp(mp_float& result, const mp_float& x, int* e) +inline void eval_frexp(cpp_float& result, const cpp_float& x, int* e) { long long t; eval_frexp(result, x, &t); @@ -2651,15 +2651,15 @@ inline void eval_frexp(mp_float& result, const mp_float& x, *e = static_cast(t); } -typedef mp_number > mp_float_50; -typedef mp_number > mp_float_100; +typedef mp_number > cpp_float_50; +typedef mp_number > cpp_float_100; }} namespace std { template - class numeric_limits > > + class numeric_limits > > { public: static const bool is_specialized = true; @@ -2670,13 +2670,13 @@ namespace std static const bool is_modulo = false; static const bool is_iec559 = false; static const int digits = static_cast(((Digits10 + 1) * 1000L) / 301L); - static const int digits10 = boost::multiprecision::mp_float::mp_float_digits10; - static const int max_digits10 = boost::multiprecision::mp_float::mp_float_max_digits10; - static const boost::int64_t min_exponent = boost::multiprecision::mp_float::mp_float_min_exp; // Type differs from int. - static const boost::int64_t min_exponent10 = boost::multiprecision::mp_float::mp_float_min_exp10; // Type differs from int. - static const boost::int64_t max_exponent = boost::multiprecision::mp_float::mp_float_max_exp; // Type differs from int. - static const boost::int64_t max_exponent10 = boost::multiprecision::mp_float::mp_float_max_exp10; // Type differs from int. - static const int radix = boost::multiprecision::mp_float::mp_radix; + static const int digits10 = boost::multiprecision::cpp_float::cpp_float_digits10; + static const int max_digits10 = boost::multiprecision::cpp_float::cpp_float_max_digits10; + static const boost::int64_t min_exponent = boost::multiprecision::cpp_float::cpp_float_min_exp; // Type differs from int. + static const boost::int64_t min_exponent10 = boost::multiprecision::cpp_float::cpp_float_min_exp10; // Type differs from int. + static const boost::int64_t max_exponent = boost::multiprecision::cpp_float::cpp_float_max_exp; // Type differs from int. + static const boost::int64_t max_exponent10 = boost::multiprecision::cpp_float::cpp_float_max_exp10; // Type differs from int. + static const int radix = boost::multiprecision::cpp_float::mp_radix; static const std::float_round_style round_style = std::round_to_nearest; static const bool has_infinity = true; static const bool has_quiet_NaN = true; @@ -2686,15 +2686,15 @@ namespace std static const bool traps = false; static const bool tinyness_before = false; - static const boost::multiprecision::mp_number > (min) (void) throw() { return (boost::multiprecision::mp_float::min)(); } - static const boost::multiprecision::mp_number > (max) (void) throw() { return (boost::multiprecision::mp_float::max)(); } - static const boost::multiprecision::mp_number > lowest (void) throw() { return boost::multiprecision::mp_float::zero(); } - static const boost::multiprecision::mp_number > epsilon (void) throw() { return boost::multiprecision::mp_float::eps(); } - static const boost::multiprecision::mp_number > round_error (void) throw() { return 0.5L; } - static const boost::multiprecision::mp_number > infinity (void) throw() { return boost::multiprecision::mp_float::inf(); } - static const boost::multiprecision::mp_number > quiet_NaN (void) throw() { return boost::multiprecision::mp_float::nan(); } - static const boost::multiprecision::mp_number > signaling_NaN(void) throw() { return boost::multiprecision::mp_float::zero(); } - static const boost::multiprecision::mp_number > denorm_min (void) throw() { return boost::multiprecision::mp_float::zero(); } + static const boost::multiprecision::mp_number > (min) (void) throw() { return (boost::multiprecision::cpp_float::min)(); } + static const boost::multiprecision::mp_number > (max) (void) throw() { return (boost::multiprecision::cpp_float::max)(); } + static const boost::multiprecision::mp_number > lowest (void) throw() { return boost::multiprecision::cpp_float::zero(); } + static const boost::multiprecision::mp_number > epsilon (void) throw() { return boost::multiprecision::cpp_float::eps(); } + static const boost::multiprecision::mp_number > round_error (void) throw() { return 0.5L; } + static const boost::multiprecision::mp_number > infinity (void) throw() { return boost::multiprecision::cpp_float::inf(); } + static const boost::multiprecision::mp_number > quiet_NaN (void) throw() { return boost::multiprecision::cpp_float::nan(); } + static const boost::multiprecision::mp_number > signaling_NaN(void) throw() { return boost::multiprecision::cpp_float::zero(); } + static const boost::multiprecision::mp_number > denorm_min (void) throw() { return boost::multiprecision::cpp_float::zero(); } }; } @@ -2703,7 +2703,7 @@ namespace boost{ namespace math{ namespace policies{ template -struct precision< boost::multiprecision::mp_number >, Policy> +struct precision< boost::multiprecision::mp_number >, Policy> { typedef typename Policy::precision_type precision_type; typedef digits2<((Digits10 + 1) * 1000L) / 301L> digits_2; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 843e64cd..75fdb952 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -36,8 +36,8 @@ run test_arithmetic.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_arithmetic_mp_float ; + TEST_CPP_FLOAT + : test_arithmetic_cpp_float ; run test_arithmetic.cpp gmp : # command line @@ -146,9 +146,9 @@ run test_numeric_limits.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT + TEST_CPP_FLOAT [ check-target-builds ../config//has_mpfr : : no ] - : test_numeric_limits_mp_float ; + : test_numeric_limits_cpp_float ; run mp_number_concept_check.cpp mpfr : # command line @@ -202,8 +202,8 @@ run mp_number_concept_check.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : mp_number_concept_check_mp_float ; + TEST_CPP_FLOAT + : mp_number_concept_check_cpp_float ; run mp_number_concept_check.cpp : # command line @@ -312,50 +312,50 @@ run test_exp.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_exp_mp_float ; + TEST_CPP_FLOAT + : test_exp_cpp_float ; run test_log.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_log_mp_float ; + TEST_CPP_FLOAT + : test_log_cpp_float ; run test_pow.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_pow_mp_float ; + TEST_CPP_FLOAT + : test_pow_cpp_float ; run test_sinh.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_sinh_mp_float ; + TEST_CPP_FLOAT + : test_sinh_cpp_float ; run test_cosh.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_cosh_mp_float ; + TEST_CPP_FLOAT + : test_cosh_cpp_float ; run test_tanh.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_tanh_mp_float ; + TEST_CPP_FLOAT + : test_tanh_cpp_float ; run test_sin.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_sin_mp_float ; + TEST_CPP_FLOAT + : test_sin_cpp_float ; run test_sin.cpp gmp : # command line @@ -377,8 +377,8 @@ run test_cos.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_cos_mp_float ; + TEST_CPP_FLOAT + : test_cos_cpp_float ; run test_cos.cpp gmp : # command line @@ -400,8 +400,8 @@ run test_asin.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_asin_mp_float ; + TEST_CPP_FLOAT + : test_asin_cpp_float ; run test_asin.cpp gmp : # command line @@ -423,8 +423,8 @@ run test_acos.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_acos_mp_float ; + TEST_CPP_FLOAT + : test_acos_cpp_float ; run test_acos.cpp gmp : # command line @@ -454,8 +454,8 @@ run test_atan.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT - : test_atan_mp_float ; + TEST_CPP_FLOAT + : test_atan_cpp_float ; run test_atan.cpp mpfr : # command line @@ -489,7 +489,7 @@ run ../example/mpfr_snips.cpp mpfr : # requirements [ check-target-builds ../config//has_mpfr : : no ] ; -run ../example/mp_float_snips.cpp ; +run ../example/cpp_float_snips.cpp ; run test_round.cpp : # command line @@ -518,9 +518,9 @@ run test_round.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT + TEST_CPP_FLOAT [ check-target-builds ../config//has_mpfr : : no ] - : test_round_mp_float ; + : test_round_cpp_float ; run test_fpclassify.cpp : # command line @@ -549,7 +549,7 @@ run test_fpclassify.cpp : # command line : # input files : # requirements - TEST_MP_FLOAT + TEST_CPP_FLOAT [ check-target-builds ../config//has_mpfr : : no ] - : test_fpclassify_mp_float ; + : test_fpclassify_cpp_float ; diff --git a/test/linpack-benchmark.cpp b/test/linpack-benchmark.cpp index f4829101..42b1c3a2 100644 --- a/test/linpack-benchmark.cpp +++ b/test/linpack-benchmark.cpp @@ -25,9 +25,9 @@ typedef mpf_class real_type; #elif defined(TEST_MPFRXX) #include typedef mpfr_class real_type; -#elif defined(TEST_MP_FLOAT) -#include -typedef boost::multiprecision::mp_float_50 real_type; +#elif defined(TEST_CPP_FLOAT) +#include +typedef boost::multiprecision::cpp_float_50 real_type; #elif defined(TEST_MPFR_50) #include typedef boost::multiprecision::mpfr_float_50 real_type; @@ -102,8 +102,8 @@ extern "C" int MAIN__() #elif defined(TEST_MPFRXX) std::cout << "Testing mpfr_class at 50 decimal degits" << std::endl; mpfr_set_default_prec(((50 + 1) * 1000L) / 301L); -#elif defined(TEST_MP_FLOAT) - std::cout << "Testing mp_number >" << std::endl; +#elif defined(TEST_CPP_FLOAT) + std::cout << "Testing mp_number >" << std::endl; #else std::cout << "Testing double" << std::endl; #endif @@ -911,8 +911,8 @@ real_type epslon_(real_type *x) { #if defined(TEST_MPF_100) || defined(TEST_MPFR_100) || defined(TEST_GMPXX) || defined(TEST_MPFRXX) return std::ldexp(1.0, 1 - ((100 + 1) * 1000L) / 301L); -#elif defined(TEST_MP_FLOAT_BN) - return std::pow(10.0, 1-std::numeric_limits::digits10); +#elif defined(TEST_CPP_FLOAT_BN) + return std::pow(10.0, 1-std::numeric_limits::digits10); #else return CAST_TO_RT(std::numeric_limits::epsilon()); #endif @@ -1234,7 +1234,7 @@ mp_number >: times for array with leading dimension of1001 279.96 0.84 280.8 2.3813 0.83988 5014.3 -boost::multiprecision::ef::mp_float_50: +boost::multiprecision::ef::cpp_float_50: ~~~~~~~~~~~~~~~~~~~~~~~~~ norm. resid resid machep x(1) x(n) diff --git a/test/mp_number_concept_check.cpp b/test/mp_number_concept_check.cpp index 35872d75..675aa2b7 100644 --- a/test/mp_number_concept_check.cpp +++ b/test/mp_number_concept_check.cpp @@ -5,7 +5,7 @@ // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -// This tests two things: that mp_float_50 meets our +// This tests two things: that cpp_float_50 meets our // conceptual requirements, and that we can instantiate // all our distributions and special functions on this type. // @@ -21,7 +21,7 @@ #endif #if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) \ - && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR_50)\ + && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR_50)\ && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) # define TEST_MPF_50 # define TEST_BACKEND @@ -31,7 +31,7 @@ # define TEST_MPFR_15 # define TEST_MPFR_17 # define TEST_MPFR_30 -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -48,8 +48,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif #if defined(TEST_MPFR_50) || defined(TEST_MPFR_6) || defined(TEST_MPFR_15) || defined(TEST_MPFR_17) || defined(TEST_MPFR_30) #include @@ -81,8 +81,8 @@ void foo() #ifdef TEST_MPFR_30 instantiate(boost::multiprecision::mp_number >()); #endif -#ifdef TEST_MP_FLOAT - instantiate(boost::multiprecision::mp_float_50()); +#ifdef TEST_CPP_FLOAT + instantiate(boost::multiprecision::cpp_float_50()); #endif } @@ -112,8 +112,8 @@ int main() #ifdef TEST_MPFR_50 BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); #endif -#ifdef TEST_MP_FLOAT - BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); +#ifdef TEST_CPP_FLOAT + BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); #endif } diff --git a/test/test_acos.cpp b/test/test_acos.cpp index f7e350c4..c2b1a074 100644 --- a/test/test_acos.cpp +++ b/test/test_acos.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -96,9 +96,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); } diff --git a/test/test_arithmetic.cpp b/test/test_arithmetic.cpp index aa040478..db49a85b 100644 --- a/test/test_arithmetic.cpp +++ b/test/test_arithmetic.cpp @@ -6,14 +6,14 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 # define TEST_MPF # define TEST_BACKEND # define TEST_MPZ # define TEST_MPFR # define TEST_MPFR_50 -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT # define TEST_MPQ #ifdef _MSC_VER @@ -31,8 +31,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif #if defined(TEST_MPFR) || defined(TEST_MPFR_50) #include @@ -861,8 +861,8 @@ int main() #ifdef TEST_MPQ test(); #endif -#ifdef TEST_MP_FLOAT - test(); +#ifdef TEST_CPP_FLOAT + test(); #endif #ifdef TEST_MPFR test(); diff --git a/test/test_asin.cpp b/test/test_asin.cpp index c8c1e810..2813f036 100644 --- a/test/test_asin.cpp +++ b/test/test_asin.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -93,9 +93,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); } diff --git a/test/test_atan.cpp b/test/test_atan.cpp index 0b07212f..b1176c6f 100644 --- a/test/test_atan.cpp +++ b/test/test_atan.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -237,9 +237,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); } diff --git a/test/test_cos.cpp b/test/test_cos.cpp index 53374292..aacd3ea4 100644 --- a/test/test_cos.cpp +++ b/test/test_cos.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -282,9 +282,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); } diff --git a/test/test_cosh.cpp b/test/test_cosh.cpp index 76c4f976..89a002d2 100644 --- a/test/test_cosh.cpp +++ b/test/test_cosh.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -128,9 +128,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); } diff --git a/test/test_exp.cpp b/test/test_exp.cpp index 8f397d9e..a8cc428a 100644 --- a/test/test_exp.cpp +++ b/test/test_exp.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -173,9 +173,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); } diff --git a/test/test_fpclassify.cpp b/test/test_fpclassify.cpp index 044f8462..374382a8 100644 --- a/test/test_fpclassify.cpp +++ b/test/test_fpclassify.cpp @@ -10,11 +10,11 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 # define TEST_MPFR_50 # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -34,8 +34,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif #ifdef _MSC_VER @@ -312,9 +312,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif #ifdef TEST_BACKEND test >(); diff --git a/test/test_log.cpp b/test/test_log.cpp index 8c6e4b19..49c6d275 100644 --- a/test/test_log.cpp +++ b/test/test_log.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -166,7 +166,11 @@ void test() e = relative_error(val, T(-data[k])); err = e.template convert_to(); if(err > max_err) + { max_err = err; + std::cout << val << std::endl; + std::cout << T(-data[k]) << std::endl; + } val = boost::multiprecision::log10(tenth + pi * (100 * k) * (100 * k)); e = relative_error(val, T(data[k] / logten)); @@ -199,9 +203,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); } diff --git a/test/test_numeric_limits.cpp b/test/test_numeric_limits.cpp index 0dc9e7d0..ce87c5d6 100644 --- a/test/test_numeric_limits.cpp +++ b/test/test_numeric_limits.cpp @@ -5,14 +5,14 @@ #include -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 # define TEST_MPF # define TEST_BACKEND # define TEST_MPZ # define TEST_MPFR # define TEST_MPFR_50 -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT # define TEST_MPQ #ifdef _MSC_VER @@ -30,8 +30,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif #if defined(TEST_MPFR) || defined(TEST_MPFR_50) #include @@ -159,9 +159,9 @@ int main() #ifdef TEST_MPQ test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif #ifdef TEST_MPFR test(); diff --git a/test/test_pow.cpp b/test/test_pow.cpp index a8ba5495..096a56c1 100644 --- a/test/test_pow.cpp +++ b/test/test_pow.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT # define TEST_MPFR_50 #ifdef _MSC_VER @@ -37,8 +37,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -576,9 +576,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); } diff --git a/test/test_round.cpp b/test/test_round.cpp index 31312c2f..5d0e2923 100644 --- a/test/test_round.cpp +++ b/test/test_round.cpp @@ -16,11 +16,11 @@ catch(...){ BOOST_ERROR("Incorrect exception type thrown"); } -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 # define TEST_MPFR_50 # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -40,8 +40,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif boost::mt19937 rng; @@ -387,9 +387,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif #ifdef TEST_BACKEND test >(); diff --git a/test/test_sin.cpp b/test/test_sin.cpp index 702e1d06..e5ecbeb6 100644 --- a/test/test_sin.cpp +++ b/test/test_sin.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -231,7 +231,12 @@ T("8.650871796830672527081873591655777773059986288175183143531618768919892399328 T e = relative_error(val, small_data[k]); unsigned err = e.template convert_to(); if(err > max_err) + { + std::cout << val << std::endl; + std::cout << small_data[k] << std::endl; + std::cout << e << std::endl; max_err = err; + } val = sin(-(euler_gamma + k) / 53); e = relative_error(val, T(-small_data[k])); err = e.template convert_to(); @@ -285,8 +290,8 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); +#ifdef TEST_CPP_FLOAT + test(); #endif return boost::report_errors(); } diff --git a/test/test_sinh.cpp b/test/test_sinh.cpp index bddad689..8a626c99 100644 --- a/test/test_sinh.cpp +++ b/test/test_sinh.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -128,9 +128,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); } diff --git a/test/test_tanh.cpp b/test/test_tanh.cpp index d226fc95..9b62aea8 100644 --- a/test/test_tanh.cpp +++ b/test/test_tanh.cpp @@ -12,11 +12,11 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_MP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) # define TEST_MPF_50 //# define TEST_MPF # define TEST_BACKEND -# define TEST_MP_FLOAT +# define TEST_CPP_FLOAT #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,8 +36,8 @@ #ifdef TEST_BACKEND #include #endif -#ifdef TEST_MP_FLOAT -#include +#ifdef TEST_CPP_FLOAT +#include #endif template @@ -128,9 +128,9 @@ int main() test(); test(); #endif -#ifdef TEST_MP_FLOAT - test(); - test(); +#ifdef TEST_CPP_FLOAT + test(); + test(); #endif return boost::report_errors(); }