From 439b12efeb58dc463bba69f392bdc82fed59a5fe Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Wed, 29 Jan 2020 18:55:07 +0000 Subject: [PATCH 1/4] Quad double: Add initial/tentative support for libqd. See https://github.com/boostorg/multiprecision/issues/184. --- include/boost/multiprecision/quad_double.hpp | 660 +++++++++++++++++++ test/test_arithmetic_qd.cpp | 18 + 2 files changed, 678 insertions(+) create mode 100644 include/boost/multiprecision/quad_double.hpp create mode 100644 test/test_arithmetic_qd.cpp diff --git a/include/boost/multiprecision/quad_double.hpp b/include/boost/multiprecision/quad_double.hpp new file mode 100644 index 000000000..71a43f528 --- /dev/null +++ b/include/boost/multiprecision/quad_double.hpp @@ -0,0 +1,660 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_MATH_FLOAT_BACKEND_HPP +#define BOOST_MATH_FLOAT_BACKEND_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace multiprecision { +namespace backends { + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable : 4389 4244 4018 4244 4127) +#endif + +struct quad_double_backend +{ + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; + typedef mpl::list float_types; + typedef int exponent_type; + + quad_double_backend() : m_value(0) {} + quad_double_backend(qd_real const& r) : m_value(r) {} + quad_double_backend(const char* s) + { + *this = s; + } + quad_double_backend(const quad_double_backend& o) : m_value(o.m_value) {} + quad_double_backend(short i) + { + m_value[0] = i; + m_value[1] = m_value[2] = m_value[3] = 0; + } + quad_double_backend(double i) + { + m_value[0] = i; + m_value[1] = m_value[2] = m_value[3] = 0; + } + quad_double_backend(unsigned short i) + { + m_value[0] = i; + m_value[1] = m_value[2] = m_value[3] = 0; + } + quad_double_backend(long long i) + { + *this = i < 0 ? static_cast(-i) : static_cast(i); + if (i < 0) + this->negate(); + } + quad_double_backend(unsigned long long i) + { + *this = i; + } + quad_double_backend& operator=(const quad_double_backend& o) + { + m_value = o.m_value; + return *this; + } + quad_double_backend& operator=(const qd_real& o) + { + m_value = o; + return *this; + } + quad_double_backend& operator=(unsigned long long i) + { + m_value[0] = static_cast(i); + m_value[1] = m_value[2] = m_value[3] = 0; + i -= static_cast(m_value[0]); + while (i) + { + double d = static_cast(i); + m_value += i; + i -= static_cast(d); + } + return *this; + } + quad_double_backend& operator=(long long i) + { + *this = static_cast(i > 0 ? i : -i); + if (i < 0) + this->negate(); + return *this; + } + quad_double_backend& operator=(short i) + { + m_value[0] = i; + m_value[1] = m_value[2] = m_value[3] = 0; + return *this; + } + quad_double_backend& operator=(unsigned short i) + { + m_value[0] = i; + m_value[1] = m_value[2] = m_value[3] = 0; + return *this; + } + quad_double_backend& operator=(long double i) + { + bool isneg = i < 0; + if (isneg) + i = -i; + m_value[0] = static_cast(i); + m_value[1] = m_value[2] = m_value[3] = 0; + i -= m_value[0]; + while (i) + { + double d = static_cast(i); + m_value += i; + i -= d; + } + return *this; + } + quad_double_backend& operator=(double i) + { + m_value[0] = i; + m_value[1] = m_value[2] = m_value[3] = 0; + return *this; + } + quad_double_backend& operator=(const char* s) + { + detail::convert_from_string(*this, s); + return *this; + } + void swap(quad_double_backend& o) + { + std::swap(m_value, o.m_value); + } + std::string str(std::streamsize digits, std::ios_base::fmtflags f) const + { + if (digits == 0) + digits = std::numeric_limits::digits10 + 3; + return boost::multiprecision::detail::convert_to_string(*this, digits, f); + } + void negate() + { + m_value = -m_value; + } + int compare(const quad_double_backend& o) const + { + return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0); + } + template + typename enable_if, int>::type compare(A i) const + { + quad_double_backend t(i); + return compare(t); + } + qd_real& data() { return m_value; } + const qd_real& data() const { return m_value; } + + private: + qd_real m_value; +}; + +template +typename boost::disable_if_c::value, R>::type minus_max() +{ + return -(std::numeric_limits::max)(); +} +template +typename boost::enable_if_c::value, R>::type minus_max() +{ + return 0; +} + +template +inline typename enable_if_c::value>::type eval_convert_to(R* result, const quad_double_backend& backend) +{ + typedef typename boost::common_type::type c_type; + + if ((backend.data()[0] < 0) && !std::numeric_limits::is_signed) + BOOST_THROW_EXCEPTION(std::range_error("Attempt to convert negative number to unsigned type.")); + + BOOST_CONSTEXPR const c_type max = static_cast((std::numeric_limits::max)()); + BOOST_CONSTEXPR const c_type min = static_cast((std::numeric_limits::min)()); + c_type ct = std::fabs(backend.data()[0]); + + if (ct > max) + if (!boost::is_unsigned::value) + *result = backend.data()[0] >= 0 ? (std::numeric_limits::max)() : minus_max(); + else + *result = (std::numeric_limits::max)(); + else + { + *result = backend.data()[0]; + *result += backend.data()[1]; + *result += backend.data()[2]; + *result += backend.data()[3]; + } +} + +template +inline typename disable_if_c::value>::type eval_convert_to(R* result, const quad_double_backend& backend) +{ + *result = backend.data()[0]; + *result += backend.data()[1]; + *result += backend.data()[2]; + *result += backend.data()[3]; +} + + +inline bool eval_eq(const quad_double_backend& a, const quad_double_backend& b) +{ + return a.data() == b.data(); +} + +inline bool eval_lt(const quad_double_backend& a, const quad_double_backend& b) +{ + return a.data() < b.data(); +} + +inline bool eval_gt(const quad_double_backend& a, const quad_double_backend& b) +{ + return a.data() > b.data(); +} + + +inline void eval_add(quad_double_backend& result, const quad_double_backend& o) +{ + if ((boost::math::isinf)(result.data()[0])){} + else if ((boost::math::isinf)(o.data()[0])) + result.data() = o.data(); + else + result.data() += o.data(); +} + +inline void eval_subtract(quad_double_backend& result, const quad_double_backend& o) +{ + if ((boost::math::isinf)(result.data()[0])) {} + else if ((boost::math::isinf)(o.data()[0])) + result.data() = -o.data(); + else + result.data() -= o.data(); +} + +inline void eval_multiply(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() *= o.data(); +} + +inline void eval_divide(quad_double_backend& result, const quad_double_backend& o) +{ + bool i1 = (boost::math::isinf)(result.data()[0]); + bool i2 = (boost::math::isinf)(o.data()[0]); + if (i1 && !i2) {} + else if (i2 && !i1) + result.data() = 0.0; + else + result.data() /= o.data(); +} + +template +inline typename enable_if_c::value >::type eval_add(quad_double_backend& result, const A2& o) +{ + if ((boost::math::isinf)(result.data()[0])) {} + else if ((boost::math::isinf)(o)) + result = o; + else + result.data() += o; +} +template +inline typename enable_if_c::value && !is_floating_point::value>::type eval_add(quad_double_backend& result, const A2& o) +{ + if (!(boost::math::isinf)(result.data()[0])) + result.data() += o; +} +template +inline typename enable_if_c::value>::type eval_subtract(quad_double_backend& result, const A2& o) +{ + if ((boost::math::isinf)(result.data()[0])) {} + else if ((boost::math::isinf)(o)) + result.data() = -o; + else + result.data() -= o; +} +template +inline typename enable_if_c::value && !is_floating_point::value>::type eval_subtract(quad_double_backend& result, const A2& o) +{ + if (!(boost::math::isinf)(result.data()[0])) + result.data() -= o; +} +template +inline typename enable_if >::type eval_multiply(quad_double_backend& result, const A2& o) +{ + result.data() *= o; +} +template +inline typename enable_if_c::value>::type +eval_divide(quad_double_backend& result, const A2& o) +{ + bool i1 = (boost::math::isinf)(result.data()[0]); + bool i2 = (boost::math::isinf)(o); + if (i1 && !i2) {} + else if (i2 && !i1) + result.data() = 0.0; + else + result.data() /= o; +} +template +inline typename enable_if_c::value && !is_floating_point::value>::type +eval_divide(quad_double_backend& result, const A2& o) +{ + bool i1 = (boost::math::isinf)(result.data()[0]); + if (!i1) + result.data() /= o; +} + + +inline void eval_add(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) +{ + if((boost::math::isinf)(a.data()[0])) + result.data() = a.data(); + else if((boost::math::isinf)(b.data()[0])) + result.data() = b.data(); + else + result.data() = a.data() + b.data(); +} + +inline void eval_subtract(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) +{ + if ((boost::math::isinf)(a.data()[0])) + result.data() = a.data(); + else if ((boost::math::isinf)(b.data()[0])) + result.data() = -b.data(); + else + result.data() = a.data() - b.data(); +} + +inline void eval_multiply(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) +{ + result.data() = a.data() * b.data(); +} + +inline void eval_divide(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) +{ + bool i1 = (boost::math::isinf)(a.data()[0]); + bool i2 = (boost::math::isinf)(b.data()[0]); + if (i1 && !i2) + result.data() = a.data(); + else if (i2 && !i1) + result.data() = 0.0; + else + result.data() = a.data() / b.data(); +} + + +template +inline typename enable_if_c::value>::type eval_add(quad_double_backend& result, const quad_double_backend& a, const A2& b) +{ + if ((boost::math::isinf)(a.data()[0])) + result.data() = a.data(); + else if ((boost::math::isinf)(b)) + result = b; + else + result.data() = a.data() + b; +} +template +inline typename enable_if_c::value && !is_floating_point::value>::type eval_add(quad_double_backend& result, const quad_double_backend& a, const A2& b) +{ + if ((boost::math::isinf)(a.data()[0])) + result.data() = a.data(); + else + result.data() = a.data() + b; +} +template +inline typename enable_if_c::value>::type eval_subtract(quad_double_backend& result, const quad_double_backend& a, const A2& b) +{ + if ((boost::math::isinf)(a.data()[0])) + result.data() = a.data(); + else if ((boost::math::isinf)(b)) + result.data() = -b; + else + result.data() = a.data() - b; +} +template +inline typename enable_if_c::value && !is_floating_point::value>::type eval_subtract(quad_double_backend& result, const quad_double_backend& a, const A2& b) +{ + if ((boost::math::isinf)(a.data()[0])) + result.data() = a.data(); + else + result.data() = a.data() - b; +} +template +inline typename enable_if >::type eval_multiply(quad_double_backend& result, const quad_double_backend& a, const A2& b) +{ + result.data() = a.data() * b; +} +template +inline typename enable_if_c::value>::type +eval_divide(quad_double_backend& result, const quad_double_backend& a, const A2& b) +{ + bool i1 = (boost::math::isinf)(a.data()[0]); + bool i2 = (boost::math::isinf)(b); + if (i1 && !i2) + result.data() = a.data(); + else if (i2 && !i1) + result.data() = 0.0; + else + result.data() = a.data() / b; +} +template +inline typename enable_if_c::value && !is_floating_point::value>::type +eval_divide(quad_double_backend& result, const quad_double_backend& a, const A2& b) +{ + bool i1 = (boost::math::isinf)(a.data()[0]); + if (i1) + result.data() = a.data(); + else + result.data() = a.data() / b; +} + + +inline bool eval_is_zero(const quad_double_backend& val) +{ + return val.data() == 0; +} + + +inline int eval_get_sign(const quad_double_backend& val) +{ + return val.data() == 0 ? 0 : val.data() < 0 ? -1 : 1; +} + +inline void eval_abs(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = abs(o.data()); +} + + +inline void eval_fabs(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = abs(o.data()); +} + + +inline void eval_floor(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = floor(o.data()); +} + + +inline void eval_ceil(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = ceil(o.data()); +} + + +inline void eval_sqrt(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = sqrt(o.data()); +} + + +inline int eval_fpclassify(const quad_double_backend& o) +{ + return (boost::math::fpclassify)(o.data()[0]); +} + + +inline void eval_trunc(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = boost::math::trunc(o.data()); +} + + +inline void eval_round(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = boost::math::round(o.data()); +} + + +inline void eval_frexp(quad_double_backend& result, const quad_double_backend& a, int* v) +{ + result.data()[0] = std::frexp(a.data()[0], v); + result.data()[1] = std::ldexp(a.data()[1], -*v); + result.data()[2] = std::ldexp(a.data()[2], -*v); + result.data()[3] = std::ldexp(a.data()[3], -*v); +} + + +inline void eval_ldexp(quad_double_backend& result, const quad_double_backend& a, int v) +{ + result.data() = ldexp(a.data(), v); +} + + +inline void eval_exp(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = exp(o.data()); +} + + +inline void eval_log(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = log(o.data()); +} + + +inline void eval_log10(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = log10(o.data()); +} + + +inline void eval_sin(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = sin(o.data()); +} + + +inline void eval_cos(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = cos(o.data()); +} + + +inline void eval_tan(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = tan(o.data()); +} + + +inline void eval_acos(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = acos(o.data()); +} + + +inline void eval_asin(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = asin(o.data()); +} + + +inline void eval_atan(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = atan(o.data()); +} + + +inline void eval_sinh(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = sinh(o.data()); +} + + +inline void eval_cosh(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = cosh(o.data()); +} + + +inline void eval_tanh(quad_double_backend& result, const quad_double_backend& o) +{ + result.data() = tanh(o.data()); +} + + +inline void eval_fmod(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) +{ + result.data() = fmod(a.data(), b.data()); +} + + +inline void eval_pow(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) +{ + result.data() = pow(a.data(), b.data()); +} + + +inline void eval_atan2(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) +{ + result.data() = atan2(a.data(), b.data()); +} + +inline std::size_t hash_value(const quad_double_backend& a) +{ + boost::hash hasher; + std::size_t result = hasher(a.data()[0]); + boost::hash_combine(result, hasher(a.data()[1])); + boost::hash_combine(result, hasher(a.data()[2])); + boost::hash_combine(result, hasher(a.data()[3])); + return result; +} + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +} // namespace backends + +using boost::multiprecision::backends::quad_double_backend; + +typedef number quad_double; + +template<> +struct number_category : public mpl::int_ +{}; + +namespace detail { +#if 0 +template +struct double_precision_type; + +template +struct double_precision_type > +{ + typedef number::type>, ET> type; +}; +template <> +struct double_precision_type > +{ + typedef quad_double_backend type; +}; +#endif +} // namespace detail + +}} // namespace boost::multiprecision + +namespace std { + +template +class numeric_limits > : public std::numeric_limits +{ + typedef std::numeric_limits base_type; + typedef boost::multiprecision::number number_type; + + public: + BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3; + BOOST_STATIC_CONSTEXPR number_type(min)() BOOST_NOEXCEPT { return (base_type::min)(); } + BOOST_STATIC_CONSTEXPR number_type(max)() BOOST_NOEXCEPT { return (base_type::max)(); } + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_NOEXCEPT { return -(max)(); } + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_NOEXCEPT { return base_type::epsilon(); } + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_NOEXCEPT { return epsilon() / 2; } + BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_NOEXCEPT { return base_type::infinity(); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_NOEXCEPT { return base_type::quiet_NaN(); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_NOEXCEPT { return base_type::signaling_NaN(); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_NOEXCEPT { return base_type::denorm_min(); } +}; + +template +BOOST_CONSTEXPR_OR_CONST int numeric_limits >::max_digits10; + +} // namespace std + +#endif diff --git a/test/test_arithmetic_qd.cpp b/test/test_arithmetic_qd.cpp new file mode 100644 index 000000000..856a684f9 --- /dev/null +++ b/test/test_arithmetic_qd.cpp @@ -0,0 +1,18 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt + +#ifdef _MSC_VER +#define _SCL_SECURE_NO_WARNINGS +#endif + +#include + +#include "test_arithmetic.hpp" + +int main() +{ + test(); + return boost::report_errors(); +} From d3acb645be4a0d735e5581ea93e3cef93b4a2405 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Mon, 3 Feb 2020 19:58:14 +0000 Subject: [PATCH 2/4] Fix up quad_double C99 math functions. Note that appendix F tests (errno values) do not pass. --- include/boost/multiprecision/quad_double.hpp | 97 ++++++++++++++------ test/test_sf_import_c99.cpp | 10 +- 2 files changed, 76 insertions(+), 31 deletions(-) diff --git a/include/boost/multiprecision/quad_double.hpp b/include/boost/multiprecision/quad_double.hpp index 71a43f528..62f483baf 100644 --- a/include/boost/multiprecision/quad_double.hpp +++ b/include/boost/multiprecision/quad_double.hpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace boost { @@ -78,14 +79,17 @@ struct quad_double_backend } quad_double_backend& operator=(unsigned long long i) { - m_value[0] = static_cast(i); + static const unsigned long long mask = (2uLL << 50) - 1; + + m_value[0] = static_cast(i & mask); m_value[1] = m_value[2] = m_value[3] = 0; - i -= static_cast(m_value[0]); + i >>= 50; + int shift = 50; while (i) { - double d = static_cast(i); - m_value += i; - i -= static_cast(d); + m_value += std::ldexp(static_cast(i & mask), shift); + i >>= 50; + shift += 50; } return *this; } @@ -132,7 +136,7 @@ struct quad_double_backend } quad_double_backend& operator=(const char* s) { - detail::convert_from_string(*this, s); + boost::multiprecision::detail::convert_from_string(*this, s); return *this; } void swap(quad_double_backend& o) @@ -473,13 +477,40 @@ inline int eval_fpclassify(const quad_double_backend& o) inline void eval_trunc(quad_double_backend& result, const quad_double_backend& o) { - result.data() = boost::math::trunc(o.data()); + if (o.data()[0] < 0) + result.data() = ceil(o.data()); + else + result.data() = floor(o.data()); } inline void eval_round(quad_double_backend& result, const quad_double_backend& o) { - result.data() = boost::math::round(o.data()); + qd_real const& v = o.data(); + // + // The logic here is rather convoluted, but avoids a number of traps, + // see discussion here https://github.com/boostorg/math/pull/8 + // + if (-0.5 < v && v < 0.5) + { + // special case to avoid rounding error on the direct + // predecessor of +0.5 resp. the direct successor of -0.5 in + // IEEE floating point types + result = 0uLL; + } + else if (v > 0) + { + // subtract v from ceil(v) first in order to avoid rounding + // errors on largest representable integer numbers + qd_real c(ceil(v)); + result = 0.5 < c - v ? c - 1 : c; + } + else + { + // see former branch + qd_real f(floor(v)); + result = 0.5 < v - f ? f + 1 : f; + } } @@ -611,23 +642,21 @@ template<> struct number_category : public mpl::int_ {}; -namespace detail { -#if 0 -template -struct double_precision_type; - -template -struct double_precision_type > +template +inline boost::multiprecision::number asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number& arg) { - typedef number::type>, ET> type; -}; -template <> -struct double_precision_type > + return asinh(arg.backend().data()); +} +template +inline boost::multiprecision::number acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number& arg) { - typedef quad_double_backend type; -}; -#endif -} // namespace detail + return acosh(arg.backend().data()); +} +template +inline boost::multiprecision::number atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number& arg) +{ + return atanh(arg.backend().data()); +} }} // namespace boost::multiprecision @@ -641,15 +670,23 @@ class numeric_limits::infinity(); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_NOEXCEPT { return std::numeric_limits::quiet_NaN(); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_NOEXCEPT { return std::numeric_limits::signaling_NaN(); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_NOEXCEPT { return std::numeric_limits::denorm_min(); } }; template diff --git a/test/test_sf_import_c99.cpp b/test/test_sf_import_c99.cpp index b901eaf1f..18fefdd2a 100644 --- a/test/test_sf_import_c99.cpp +++ b/test/test_sf_import_c99.cpp @@ -7,7 +7,7 @@ #pragma warning(disable : 4127) // conditional expression is constant #endif -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_CPP_DEC_FLOAT_2) && !defined(TEST_CPP_DEC_FLOAT_3) && !defined(TEST_CPP_DEC_FLOAT_4) && !defined(TEST_CPP_DEC_FLOAT_5) && !defined(TEST_CPP_DEC_FLOAT_6) && !defined(TEST_CPP_BIN_FLOAT_2) && !defined(TEST_CPP_BIN_FLOAT_3) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_CPP_DEC_FLOAT_2) && !defined(TEST_CPP_DEC_FLOAT_3) && !defined(TEST_CPP_DEC_FLOAT_4) && !defined(TEST_CPP_DEC_FLOAT_5) && !defined(TEST_CPP_DEC_FLOAT_6) && !defined(TEST_CPP_BIN_FLOAT_2) && !defined(TEST_CPP_BIN_FLOAT_3) && !defined(TEST_QUAD_DOUBLE) #define TEST_MPF_50 #define TEST_MPFR_50 #define TEST_MPFI_50 @@ -21,6 +21,7 @@ #define TEST_CPP_BIN_FLOAT #define TEST_CPP_BIN_FLOAT_2 #define TEST_CPP_BIN_FLOAT_3 +#define TEST_QUAD_DOUBLE #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -50,6 +51,9 @@ #ifdef TEST_FLOAT128 #include #endif +#ifdef TEST_QUAD_DOUBLE +#include +#endif #include #include @@ -2198,6 +2202,10 @@ int main() test_c99_appendix_F(); test_c99_appendix_F_tgammaq_addon_for_float128(); #endif +#ifdef TEST_QUAD_DOUBLE + test(); + //test_c99_appendix_F(); +#endif return boost::report_errors(); } From 727d58343452a742b9244e89b96ec7b0c0c19be7 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Fri, 21 Feb 2020 09:10:52 +0000 Subject: [PATCH 3/4] quad_double: big bug fix. Greatly improve testing. Correct and be consistent with numeric_limits<>::round_error(). --- .travis.yml | 7 + config/Jamfile.v2 | 3 + config/has_qd.cpp | 12 + .../boost/multiprecision/debug_adaptor.hpp | 2 +- include/boost/multiprecision/gmp.hpp | 2 +- .../boost/multiprecision/logged_adaptor.hpp | 2 +- include/boost/multiprecision/mpfi.hpp | 4 +- include/boost/multiprecision/mpfr.hpp | 6 +- include/boost/multiprecision/quad_double.hpp | 250 +++++++----------- .../boost/multiprecision/rational_adaptor.hpp | 2 +- test/Jamfile.v2 | 23 ++ test/concepts/number_concept_check.cpp | 9 +- test/concepts/sf_concept_check_basic.cpp | 9 +- test/concepts/sf_concept_check_bessel.cpp | 9 +- test/concepts/sf_concept_check_beta.cpp | 9 +- test/concepts/sf_concept_check_beta_2.cpp | 9 +- test/concepts/sf_concept_check_beta_3.cpp | 9 +- test/concepts/sf_concept_check_elliptic.cpp | 9 +- test/concepts/sf_concept_check_gamma.cpp | 9 +- test/concepts/sf_concept_check_poly.cpp | 9 +- test/test_acos.cpp | 9 +- test/test_arithmetic.hpp | 12 + test/test_asin.cpp | 9 +- test/test_atan.cpp | 9 +- test/test_constants.cpp | 9 +- test/test_cos.cpp | 9 +- test/test_cosh.cpp | 9 +- test/test_exp.cpp | 11 +- test/test_fpclassify.cpp | 9 +- test/test_hash.cpp | 6 + test/test_log.cpp | 9 +- test/test_numeric_limits.cpp | 9 +- test/test_pow.cpp | 19 +- test/test_round.cpp | 9 +- test/test_sin.cpp | 9 +- test/test_sinh.cpp | 16 +- test/test_sqrt.cpp | 9 +- test/test_tan.cpp | 9 +- test/test_tanh.cpp | 16 +- 39 files changed, 403 insertions(+), 188 deletions(-) create mode 100644 config/has_qd.cpp diff --git a/.travis.yml b/.travis.yml index c8438f4d7..3c5e053e9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -530,6 +530,7 @@ matrix: - libmpc-dev - libmpfi-dev - libtommath-dev + - libqd-dev sources: - ubuntu-toolchain-r-test @@ -544,6 +545,7 @@ matrix: - libmpc-dev - libmpfi-dev - libtommath-dev + - libqd-dev sources: - ubuntu-toolchain-r-test @@ -558,6 +560,7 @@ matrix: - libmpc-dev - libmpfi-dev - libtommath-dev + - libqd-dev sources: - ubuntu-toolchain-r-test @@ -572,6 +575,7 @@ matrix: - libmpc-dev - libmpfi-dev - libtommath-dev + - libqd-dev sources: - ubuntu-toolchain-r-test @@ -586,6 +590,7 @@ matrix: - libmpc-dev - libmpfi-dev - libtommath-dev + - libqd-dev sources: - ubuntu-toolchain-r-test @@ -600,6 +605,7 @@ matrix: - libmpc-dev - libmpfi-dev - libtommath-dev + - libqd-dev sources: - ubuntu-toolchain-r-test @@ -614,6 +620,7 @@ matrix: - libmpc-dev - libmpfi-dev - libtommath-dev + - libqd-dev sources: - ubuntu-toolchain-r-test diff --git a/config/Jamfile.v2 b/config/Jamfile.v2 index d5d2fee58..824005f16 100644 --- a/config/Jamfile.v2 +++ b/config/Jamfile.v2 @@ -43,6 +43,7 @@ lib mpc ; lib quadmath ; lib tommath ; lib f2c ; +lib qd ; actions mp_simple_run_action { @@ -60,6 +61,7 @@ rule mp-run-simple ( sources + : args * : input-files * : requirements * : targe mp-run-simple has_gmp.cpp gmp : : : $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx : has_gmp ; +mp-run-simple has_qd.cpp qd : : : : has_qd ; mp-run-simple has_mpfr.cpp mpfr gmp : : : $(mpfr_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx $(gmp_path) : has_mpfr ; mp-run-simple has_mpfi.cpp mpfi mpfr gmp : : : @@ -76,6 +78,7 @@ obj has_is_constant_evaluated : has_is_constant_evaluated.cpp ; obj has_constexpr_limits : has_constexpr_limits_cmd.cpp : -fconstexpr-ops-limit=268435456 ; explicit has_gmp ; +explicit has_qd ; explicit has_mpfr ; explicit has_mpfi ; explicit has_tommath ; diff --git a/config/has_qd.cpp b/config/has_qd.cpp new file mode 100644 index 000000000..2e87abfaf --- /dev/null +++ b/config/has_qd.cpp @@ -0,0 +1,12 @@ +// Copyright John Maddock 2020. +// Use, modification and distribution are subject to 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) + +#include + +int main() +{ + qd_real q; + return 0; +} diff --git a/include/boost/multiprecision/debug_adaptor.hpp b/include/boost/multiprecision/debug_adaptor.hpp index 826c76d74..b6842e7a6 100644 --- a/include/boost/multiprecision/debug_adaptor.hpp +++ b/include/boost/multiprecision/debug_adaptor.hpp @@ -510,7 +510,7 @@ class numeric_limits value; if (!value.first) diff --git a/include/boost/multiprecision/logged_adaptor.hpp b/include/boost/multiprecision/logged_adaptor.hpp index caa9c779e..02f8c0b0b 100644 --- a/include/boost/multiprecision/logged_adaptor.hpp +++ b/include/boost/multiprecision/logged_adaptor.hpp @@ -606,7 +606,7 @@ class numeric_limits value; if (!value.first) { value.first = true; - value.second = 1; + value.second = 0.5; mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), 1); } return value.second; diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index 38dc629ce..ea3926ea8 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -2381,13 +2381,13 @@ class numeric_limits value; if (!value.first) { value.first = true; - value.second = 1; + value.second = 0.5; mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), 1, GMP_RNDN); } return value.second; @@ -2576,7 +2576,7 @@ class numeric_limits +struct number_category : public mpl::int_ +{}; + +namespace backends { + struct quad_double_backend { - typedef mpl::list signed_types; - typedef mpl::list unsigned_types; - typedef mpl::list float_types; - typedef int exponent_type; + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; + typedef mpl::list float_types; + typedef int exponent_type; quad_double_backend() : m_value(0) {} quad_double_backend(qd_real const& r) : m_value(r) {} @@ -57,16 +67,6 @@ struct quad_double_backend m_value[0] = i; m_value[1] = m_value[2] = m_value[3] = 0; } - quad_double_backend(long long i) - { - *this = i < 0 ? static_cast(-i) : static_cast(i); - if (i < 0) - this->negate(); - } - quad_double_backend(unsigned long long i) - { - *this = i; - } quad_double_backend& operator=(const quad_double_backend& o) { m_value = o.m_value; @@ -79,9 +79,9 @@ struct quad_double_backend } quad_double_backend& operator=(unsigned long long i) { - static const unsigned long long mask = (2uLL << 50) - 1; + static const unsigned long long mask = (1uLL << 50) - 1; - m_value[0] = static_cast(i & mask); + m_value[0] = static_cast(i & mask); m_value[1] = m_value[2] = m_value[3] = 0; i >>= 50; int shift = 50; @@ -95,9 +95,13 @@ struct quad_double_backend } quad_double_backend& operator=(long long i) { - *this = static_cast(i > 0 ? i : -i); if (i < 0) + { + *this = static_cast(-(i + 1)) + 1u; this->negate(); + } + else + *this = static_cast(i); return *this; } quad_double_backend& operator=(short i) @@ -160,10 +164,11 @@ struct quad_double_backend template typename enable_if, int>::type compare(A i) const { - quad_double_backend t(i); + quad_double_backend t; + t = i; return compare(t); } - qd_real& data() { return m_value; } + qd_real& data() { return m_value; } const qd_real& data() const { return m_value; } private: @@ -173,7 +178,7 @@ struct quad_double_backend template typename boost::disable_if_c::value, R>::type minus_max() { - return -(std::numeric_limits::max)(); + return boost::is_signed::value ? (std::numeric_limits::min)() : -(std::numeric_limits::max)(); } template typename boost::enable_if_c::value, R>::type minus_max() @@ -185,13 +190,13 @@ template inline typename enable_if_c::value>::type eval_convert_to(R* result, const quad_double_backend& backend) { typedef typename boost::common_type::type c_type; - + if ((backend.data()[0] < 0) && !std::numeric_limits::is_signed) BOOST_THROW_EXCEPTION(std::range_error("Attempt to convert negative number to unsigned type.")); - BOOST_CONSTEXPR const c_type max = static_cast((std::numeric_limits::max)()); - BOOST_CONSTEXPR const c_type min = static_cast((std::numeric_limits::min)()); - c_type ct = std::fabs(backend.data()[0]); + BOOST_CONSTEXPR const c_type max = static_cast((std::numeric_limits::max)()); + BOOST_CONSTEXPR const c_type min = static_cast((std::numeric_limits::min)()); + c_type ct = std::fabs(backend.data()[0]); if (ct > max) if (!boost::is_unsigned::value) @@ -200,10 +205,10 @@ inline typename enable_if_c::value>::type eval_convert_to( *result = (std::numeric_limits::max)(); else { - *result = backend.data()[0]; - *result += backend.data()[1]; - *result += backend.data()[2]; - *result += backend.data()[3]; + *result = static_cast(backend.data()[0]); + *result += static_cast(backend.data()[1]); + *result += static_cast(backend.data()[2]); + *result += static_cast(backend.data()[3]); } } @@ -216,7 +221,6 @@ inline typename disable_if_c::value>::type eval_convert_to *result += backend.data()[3]; } - inline bool eval_eq(const quad_double_backend& a, const quad_double_backend& b) { return a.data() == b.data(); @@ -232,10 +236,11 @@ inline bool eval_gt(const quad_double_backend& a, const quad_double_backend& b) return a.data() > b.data(); } - inline void eval_add(quad_double_backend& result, const quad_double_backend& o) { - if ((boost::math::isinf)(result.data()[0])){} + if ((boost::math::isinf)(result.data()[0])) + { + } else if ((boost::math::isinf)(o.data()[0])) result.data() = o.data(); else @@ -244,7 +249,9 @@ inline void eval_add(quad_double_backend& result, const quad_double_backend& o) inline void eval_subtract(quad_double_backend& result, const quad_double_backend& o) { - if ((boost::math::isinf)(result.data()[0])) {} + if ((boost::math::isinf)(result.data()[0])) + { + } else if ((boost::math::isinf)(o.data()[0])) result.data() = -o.data(); else @@ -260,75 +267,57 @@ inline void eval_divide(quad_double_backend& result, const quad_double_backend& { bool i1 = (boost::math::isinf)(result.data()[0]); bool i2 = (boost::math::isinf)(o.data()[0]); - if (i1 && !i2) {} + if (i1 && !i2) + { + } else if (i2 && !i1) result.data() = 0.0; else result.data() /= o.data(); } -template -inline typename enable_if_c::value >::type eval_add(quad_double_backend& result, const A2& o) +inline void eval_add(quad_double_backend& result, double o) { - if ((boost::math::isinf)(result.data()[0])) {} + if ((boost::math::isinf)(result.data()[0])) + { + } else if ((boost::math::isinf)(o)) result = o; else result.data() += o; } -template -inline typename enable_if_c::value && !is_floating_point::value>::type eval_add(quad_double_backend& result, const A2& o) -{ - if (!(boost::math::isinf)(result.data()[0])) - result.data() += o; -} -template -inline typename enable_if_c::value>::type eval_subtract(quad_double_backend& result, const A2& o) +inline void eval_subtract(quad_double_backend& result, double o) { - if ((boost::math::isinf)(result.data()[0])) {} + if ((boost::math::isinf)(result.data()[0])) + { + } else if ((boost::math::isinf)(o)) result.data() = -o; else result.data() -= o; } -template -inline typename enable_if_c::value && !is_floating_point::value>::type eval_subtract(quad_double_backend& result, const A2& o) -{ - if (!(boost::math::isinf)(result.data()[0])) - result.data() -= o; -} -template -inline typename enable_if >::type eval_multiply(quad_double_backend& result, const A2& o) +inline void eval_multiply(quad_double_backend& result, double o) { result.data() *= o; } -template -inline typename enable_if_c::value>::type -eval_divide(quad_double_backend& result, const A2& o) +inline void eval_divide(quad_double_backend& result, double o) { bool i1 = (boost::math::isinf)(result.data()[0]); bool i2 = (boost::math::isinf)(o); - if (i1 && !i2) {} + if (i1 && !i2) + { + } else if (i2 && !i1) result.data() = 0.0; else result.data() /= o; } -template -inline typename enable_if_c::value && !is_floating_point::value>::type -eval_divide(quad_double_backend& result, const A2& o) -{ - bool i1 = (boost::math::isinf)(result.data()[0]); - if (!i1) - result.data() /= o; -} - inline void eval_add(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) { - if((boost::math::isinf)(a.data()[0])) + if ((boost::math::isinf)(a.data()[0])) result.data() = a.data(); - else if((boost::math::isinf)(b.data()[0])) + else if ((boost::math::isinf)(b.data()[0])) result.data() = b.data(); else result.data() = a.data() + b.data(); @@ -361,9 +350,7 @@ inline void eval_divide(quad_double_backend& result, const quad_double_backend& result.data() = a.data() / b.data(); } - -template -inline typename enable_if_c::value>::type eval_add(quad_double_backend& result, const quad_double_backend& a, const A2& b) +inline void eval_add(quad_double_backend& result, const quad_double_backend& a, double b) { if ((boost::math::isinf)(a.data()[0])) result.data() = a.data(); @@ -372,16 +359,7 @@ inline typename enable_if_c::value>::type eval_add(quad_do else result.data() = a.data() + b; } -template -inline typename enable_if_c::value && !is_floating_point::value>::type eval_add(quad_double_backend& result, const quad_double_backend& a, const A2& b) -{ - if ((boost::math::isinf)(a.data()[0])) - result.data() = a.data(); - else - result.data() = a.data() + b; -} -template -inline typename enable_if_c::value>::type eval_subtract(quad_double_backend& result, const quad_double_backend& a, const A2& b) +inline void eval_subtract(quad_double_backend& result, const quad_double_backend& a, double b) { if ((boost::math::isinf)(a.data()[0])) result.data() = a.data(); @@ -390,22 +368,11 @@ inline typename enable_if_c::value>::type eval_subtract(qu else result.data() = a.data() - b; } -template -inline typename enable_if_c::value && !is_floating_point::value>::type eval_subtract(quad_double_backend& result, const quad_double_backend& a, const A2& b) -{ - if ((boost::math::isinf)(a.data()[0])) - result.data() = a.data(); - else - result.data() = a.data() - b; -} -template -inline typename enable_if >::type eval_multiply(quad_double_backend& result, const quad_double_backend& a, const A2& b) +inline void eval_multiply(quad_double_backend& result, const quad_double_backend& a, double b) { result.data() = a.data() * b; } -template -inline typename enable_if_c::value>::type -eval_divide(quad_double_backend& result, const quad_double_backend& a, const A2& b) +inline void eval_divide(quad_double_backend& result, const quad_double_backend& a, double b) { bool i1 = (boost::math::isinf)(a.data()[0]); bool i2 = (boost::math::isinf)(b); @@ -416,24 +383,12 @@ eval_divide(quad_double_backend& result, const quad_double_backend& a, const A2& else result.data() = a.data() / b; } -template -inline typename enable_if_c::value && !is_floating_point::value>::type -eval_divide(quad_double_backend& result, const quad_double_backend& a, const A2& b) -{ - bool i1 = (boost::math::isinf)(a.data()[0]); - if (i1) - result.data() = a.data(); - else - result.data() = a.data() / b; -} - inline bool eval_is_zero(const quad_double_backend& val) { return val.data() == 0; } - inline int eval_get_sign(const quad_double_backend& val) { return val.data() == 0 ? 0 : val.data() < 0 ? -1 : 1; @@ -444,37 +399,36 @@ inline void eval_abs(quad_double_backend& result, const quad_double_backend& o) result.data() = abs(o.data()); } - inline void eval_fabs(quad_double_backend& result, const quad_double_backend& o) { result.data() = abs(o.data()); } - inline void eval_floor(quad_double_backend& result, const quad_double_backend& o) { result.data() = floor(o.data()); } - inline void eval_ceil(quad_double_backend& result, const quad_double_backend& o) { result.data() = ceil(o.data()); } - inline void eval_sqrt(quad_double_backend& result, const quad_double_backend& o) { - result.data() = sqrt(o.data()); + if (o.data()[0] > (std::numeric_limits::max)() / 4) + result.data() = 2 * sqrt(ldexp(o.data(), -2)); + else + result.data() = sqrt(o.data()); } - inline int eval_fpclassify(const quad_double_backend& o) { + if (std::fabs(o.data()[0]) && (std::fabs(o.data()[0]) < qd_real::_min_normalized)) + return FP_SUBNORMAL; return (boost::math::fpclassify)(o.data()[0]); } - inline void eval_trunc(quad_double_backend& result, const quad_double_backend& o) { if (o.data()[0] < 0) @@ -483,7 +437,6 @@ inline void eval_trunc(quad_double_backend& result, const quad_double_backend& o result.data() = floor(o.data()); } - inline void eval_round(quad_double_backend& result, const quad_double_backend& o) { qd_real const& v = o.data(); @@ -513,7 +466,6 @@ inline void eval_round(quad_double_backend& result, const quad_double_backend& o } } - inline void eval_frexp(quad_double_backend& result, const quad_double_backend& a, int* v) { result.data()[0] = std::frexp(a.data()[0], v); @@ -522,106 +474,106 @@ inline void eval_frexp(quad_double_backend& result, const quad_double_backend& a result.data()[3] = std::ldexp(a.data()[3], -*v); } - inline void eval_ldexp(quad_double_backend& result, const quad_double_backend& a, int v) { result.data() = ldexp(a.data(), v); } - inline void eval_exp(quad_double_backend& result, const quad_double_backend& o) { result.data() = exp(o.data()); } - - +/* inline void eval_log(quad_double_backend& result, const quad_double_backend& o) { result.data() = log(o.data()); } - inline void eval_log10(quad_double_backend& result, const quad_double_backend& o) { result.data() = log10(o.data()); } - - +*/ inline void eval_sin(quad_double_backend& result, const quad_double_backend& o) { result.data() = sin(o.data()); } - inline void eval_cos(quad_double_backend& result, const quad_double_backend& o) { result.data() = cos(o.data()); } - inline void eval_tan(quad_double_backend& result, const quad_double_backend& o) { result.data() = tan(o.data()); } - inline void eval_acos(quad_double_backend& result, const quad_double_backend& o) { result.data() = acos(o.data()); } - inline void eval_asin(quad_double_backend& result, const quad_double_backend& o) { result.data() = asin(o.data()); } - inline void eval_atan(quad_double_backend& result, const quad_double_backend& o) { result.data() = atan(o.data()); } - inline void eval_sinh(quad_double_backend& result, const quad_double_backend& o) { result.data() = sinh(o.data()); } - inline void eval_cosh(quad_double_backend& result, const quad_double_backend& o) { result.data() = cosh(o.data()); } - inline void eval_tanh(quad_double_backend& result, const quad_double_backend& o) { result.data() = tanh(o.data()); } - inline void eval_fmod(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) { result.data() = fmod(a.data(), b.data()); } - inline void eval_pow(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) { + boost::int64_t i = static_cast(b.data()[0]); + if (i == b.data()[0]) + { + boost::int64_t j = static_cast(b.data()[1]); + if ((b.data()[1] == j) && (b.data()[2] == 0) && (b.data()[3] == 0)) + { + default_ops::eval_pow(result, a, i + j); + return; + } + } result.data() = pow(a.data(), b.data()); } - inline void eval_atan2(quad_double_backend& result, const quad_double_backend& a, const quad_double_backend& b) { - result.data() = atan2(a.data(), b.data()); + if (std::fabs(a.data()[0]) > 2e66) + { + // No fractional part after modular reduction: + result.data() = a.data().is_negative() ? -qd_real::_pi2 : qd_real::_pi2; + } + else + result.data() = atan2(a.data(), b.data()); } inline std::size_t hash_value(const quad_double_backend& a) { boost::hash hasher; - std::size_t result = hasher(a.data()[0]); + std::size_t result = hasher(a.data()[0]); boost::hash_combine(result, hasher(a.data()[1])); boost::hash_combine(result, hasher(a.data()[2])); boost::hash_combine(result, hasher(a.data()[3])); @@ -638,10 +590,6 @@ using boost::multiprecision::backends::quad_double_backend; typedef number quad_double; -template<> -struct number_category : public mpl::int_ -{}; - template inline boost::multiprecision::number asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number& arg) { @@ -665,24 +613,24 @@ namespace std { template class numeric_limits > : public std::numeric_limits { - typedef std::numeric_limits base_type; - typedef boost::multiprecision::number number_type; + typedef std::numeric_limits base_type; + typedef boost::multiprecision::number number_type; public: - BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3; - BOOST_STATIC_CONSTEXPR number_type(min)() BOOST_NOEXCEPT - { - static const qd_real value = { 1.6259745436952323e-260 }; - return (base_type::min)(); + BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 3; + BOOST_STATIC_CONSTEXPR float_round_style round_style = std::round_indeterminate; + BOOST_STATIC_CONSTEXPR number_type(min)() BOOST_NOEXCEPT + { + return (base_type::min)(); } - BOOST_STATIC_CONSTEXPR number_type(max)() BOOST_NOEXCEPT + BOOST_STATIC_CONSTEXPR number_type(max)() BOOST_NOEXCEPT { - static const qd_real value = { 1.79769313486231570815e+308, 9.97920154767359795037e+291, 5.53956966280111259858e+275, 3.07507889307840487279e+259 }; - return value; + qd_real r = {1.79769313486231570815e+308, 9.97920154767359795037e+291, 5.53956966280111259858e+275, 3.07507889307840487279e+259}; + return r; } BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_NOEXCEPT { return -(max)(); } BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_NOEXCEPT { return 1.21543267145725e-63; } - BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_NOEXCEPT { return epsilon() / 2; } + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_NOEXCEPT { return 1; } BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_NOEXCEPT { return std::numeric_limits::infinity(); } BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_NOEXCEPT { return std::numeric_limits::quiet_NaN(); } BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_NOEXCEPT { return std::numeric_limits::signaling_NaN(); } @@ -691,6 +639,8 @@ class numeric_limits BOOST_CONSTEXPR_OR_CONST int numeric_limits >::max_digits10; +template +BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits >::round_style; } // namespace std diff --git a/include/boost/multiprecision/rational_adaptor.hpp b/include/boost/multiprecision/rational_adaptor.hpp index 2d839bb1c..8e99bc960 100644 --- a/include/boost/multiprecision/rational_adaptor.hpp +++ b/include/boost/multiprecision/rational_adaptor.hpp @@ -348,7 +348,7 @@ class numeric_limits$(gmp_path) $(mpfr_path) $(mpfr_path)/build lib mpfi : : $(gmp_path) $(mpfr_path) $(mpfr_path)/build.vc10/lib/Win32/Debug $(mpfi_path) $(mpfi_path)/src ; lib quadmath ; lib mpc ; +lib qd ; if $(tommath_path) { @@ -178,6 +179,7 @@ test-suite arithmetic_tests : [ run test_arithmetic_complex_adaptor.cpp ] [ run test_arithmetic_complex_adaptor_2.cpp ] [ run test_arithmetic_complex128.cpp : : : [ check-target-builds ../config//has_float128 : quadmath ] ] + [ run test_arithmetic_qd.cpp : : : [ check-target-builds ../config//has_qd : qd : no ] ] ; @@ -233,6 +235,13 @@ rule get_function_tests [ check-target-builds ../config//has_intel_quad : -Qoption,cpp,--extended_float_type : no ] [ check-target-builds ../config//has_float128 : quadmath ] TEST_FLOAT128 : $(source:B)_intel_quad ] ; + result += [ run $(source) no_eh_support + : # command line + : # input files + : # requirements + [ check-target-builds ../config//has_qd : qd : no ] + TEST_QD + : $(source:B)_qd ] ; } return $(result) ; } @@ -346,6 +355,13 @@ test-suite functions_and_limits : TEST_FLOAT128 [ check-target-builds ../config//has_intel_quad : -Qoption,cpp,--extended_float_type : no ] [ check-target-builds ../config//has_float128 : quadmath ] : test_numeric_limits_intel_quad ] + [ run test_numeric_limits.cpp no_eh_support + : # command line + : # input files + : # requirements + TEST_QD + [ check-target-builds ../config//has_qd : qd : no ] + : test_numeric_limits_qd ] [ run test_sf_import_c99.cpp : : : TEST_CPP_DEC_FLOAT_2 : test_sf_import_c99_cpp_dec_float_2 ] [ run test_sf_import_c99.cpp : : : TEST_CPP_DEC_FLOAT_3 : test_sf_import_c99_cpp_dec_float_3 ] @@ -1279,6 +1295,13 @@ rule get_concept_checks off space : $(source:B)_logged_adaptor ] ; + result += [ compile $(source) + : # requirements + TEST_QD + [ check-target-builds ../config//has_qd : : no ] + off + space + : $(source:B)_qd ] ; } return $(result) ; } diff --git a/test/concepts/number_concept_check.cpp b/test/concepts/number_concept_check.cpp index dc1e02398..440c1545e 100644 --- a/test/concepts/number_concept_check.cpp +++ b/test/concepts/number_concept_check.cpp @@ -19,7 +19,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_BACKEND #define TEST_MPZ @@ -32,6 +32,7 @@ #define TEST_CPP_DEC_FLOAT_NO_ET #define TEST_LOGGED_ADAPTER #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -60,6 +61,9 @@ #ifdef TEST_LOGGED_ADAPTER #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -248,4 +252,7 @@ int main() typedef boost::multiprecision::number > > num_t; test_extra(num_t()); #endif +#ifdef TEST_QD + BOOST_CONCEPT_ASSERT((boost::math::concepts::RealTypeConcept)); +#endif } diff --git a/test/concepts/sf_concept_check_basic.cpp b/test/concepts/sf_concept_check_basic.cpp index 1defde713..3d142aa35 100644 --- a/test/concepts/sf_concept_check_basic.cpp +++ b/test/concepts/sf_concept_check_basic.cpp @@ -19,7 +19,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_BACKEND #define TEST_MPZ @@ -32,6 +32,7 @@ #define TEST_CPP_DEC_FLOAT_NO_ET #define TEST_LOGGED_ADAPTER #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -60,6 +61,9 @@ #ifdef TEST_LOGGED_ADAPTER #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -153,6 +157,9 @@ void foo() #ifdef TEST_CPP_DEC_FLOAT_NO_ET test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); #endif +#ifdef TEST_QD + test_extra(boost::multiprecision::number()); +#endif #ifdef TEST_LOGGED_ADAPTER typedef boost::multiprecision::number > > num_t; test_extra(num_t()); diff --git a/test/concepts/sf_concept_check_bessel.cpp b/test/concepts/sf_concept_check_bessel.cpp index 0a5002b26..665497b83 100644 --- a/test/concepts/sf_concept_check_bessel.cpp +++ b/test/concepts/sf_concept_check_bessel.cpp @@ -19,7 +19,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_BACKEND #define TEST_MPZ @@ -32,6 +32,7 @@ #define TEST_CPP_DEC_FLOAT_NO_ET #define TEST_LOGGED_ADAPTER #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -60,6 +61,9 @@ #ifdef TEST_LOGGED_ADAPTER #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -120,6 +124,9 @@ void foo() #ifdef TEST_CPP_DEC_FLOAT_NO_ET test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); #endif +#ifdef TEST_QD + test_extra(boost::multiprecision::quad_double()); +#endif #ifdef TEST_LOGGED_ADAPTER typedef boost::multiprecision::number > > num_t; test_extra(num_t()); diff --git a/test/concepts/sf_concept_check_beta.cpp b/test/concepts/sf_concept_check_beta.cpp index 61cbdf1b4..9c9c5f8d7 100644 --- a/test/concepts/sf_concept_check_beta.cpp +++ b/test/concepts/sf_concept_check_beta.cpp @@ -19,7 +19,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_BACKEND #define TEST_MPZ @@ -32,6 +32,7 @@ #define TEST_CPP_DEC_FLOAT_NO_ET #define TEST_LOGGED_ADAPTER #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -60,6 +61,9 @@ #ifdef TEST_LOGGED_ADAPTER #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -108,6 +112,9 @@ void foo() #ifdef TEST_CPP_DEC_FLOAT_NO_ET test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); #endif +#ifdef TEST_QD + test_extra(boost::multiprecision::quad_double()); +#endif #ifdef TEST_LOGGED_ADAPTER typedef boost::multiprecision::number > > num_t; test_extra(num_t()); diff --git a/test/concepts/sf_concept_check_beta_2.cpp b/test/concepts/sf_concept_check_beta_2.cpp index aff7e5c8d..13470b1a8 100644 --- a/test/concepts/sf_concept_check_beta_2.cpp +++ b/test/concepts/sf_concept_check_beta_2.cpp @@ -19,7 +19,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_BACKEND #define TEST_MPZ @@ -32,6 +32,7 @@ #define TEST_CPP_DEC_FLOAT_NO_ET #define TEST_LOGGED_ADAPTER #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -60,6 +61,9 @@ #ifdef TEST_LOGGED_ADAPTER #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -104,6 +108,9 @@ void foo() #ifdef TEST_CPP_DEC_FLOAT_NO_ET test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); #endif +#ifdef TEST_QD + test_extra(boost::multiprecision::quad_double()); +#endif #ifdef TEST_LOGGED_ADAPTER typedef boost::multiprecision::number > > num_t; test_extra(num_t()); diff --git a/test/concepts/sf_concept_check_beta_3.cpp b/test/concepts/sf_concept_check_beta_3.cpp index fcae4078b..ba22cf770 100644 --- a/test/concepts/sf_concept_check_beta_3.cpp +++ b/test/concepts/sf_concept_check_beta_3.cpp @@ -19,7 +19,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_BACKEND #define TEST_MPZ @@ -32,6 +32,7 @@ #define TEST_CPP_DEC_FLOAT_NO_ET #define TEST_LOGGED_ADAPTER #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -60,6 +61,9 @@ #ifdef TEST_LOGGED_ADAPTER #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -106,6 +110,9 @@ void foo() #ifdef TEST_CPP_DEC_FLOAT_NO_ET test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); #endif +#ifdef TEST_QD + test_extra(boost::multiprecision::quad_double()); +#endif #ifdef TEST_LOGGED_ADAPTER typedef boost::multiprecision::number > > num_t; test_extra(num_t()); diff --git a/test/concepts/sf_concept_check_elliptic.cpp b/test/concepts/sf_concept_check_elliptic.cpp index 4d3d24b9e..a3280ee20 100644 --- a/test/concepts/sf_concept_check_elliptic.cpp +++ b/test/concepts/sf_concept_check_elliptic.cpp @@ -19,7 +19,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_BACKEND #define TEST_MPZ @@ -32,6 +32,7 @@ #define TEST_CPP_DEC_FLOAT_NO_ET #define TEST_LOGGED_ADAPTER #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -60,6 +61,9 @@ #ifdef TEST_LOGGED_ADAPTER #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -124,6 +128,9 @@ void foo() #ifdef TEST_CPP_DEC_FLOAT_NO_ET test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); #endif +#ifdef TEST_QD + test_extra(boost::multiprecision::quad_double()); +#endif #ifdef TEST_LOGGED_ADAPTER typedef boost::multiprecision::number > > num_t; test_extra(num_t()); diff --git a/test/concepts/sf_concept_check_gamma.cpp b/test/concepts/sf_concept_check_gamma.cpp index 4d879abc3..26321227c 100644 --- a/test/concepts/sf_concept_check_gamma.cpp +++ b/test/concepts/sf_concept_check_gamma.cpp @@ -19,7 +19,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_BACKEND #define TEST_MPZ @@ -32,6 +32,7 @@ #define TEST_CPP_DEC_FLOAT_NO_ET #define TEST_LOGGED_ADAPTER #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -60,6 +61,9 @@ #ifdef TEST_LOGGED_ADAPTER #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -128,6 +132,9 @@ void foo() #ifdef TEST_CPP_DEC_FLOAT_NO_ET test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); #endif +#ifdef TEST_QD + test_extra(boost::multiprecision::quad_double()); +#endif #ifdef TEST_LOGGED_ADAPTER typedef boost::multiprecision::number > > num_t; test_extra(num_t()); diff --git a/test/concepts/sf_concept_check_poly.cpp b/test/concepts/sf_concept_check_poly.cpp index a67f1d980..9eb954ca0 100644 --- a/test/concepts/sf_concept_check_poly.cpp +++ b/test/concepts/sf_concept_check_poly.cpp @@ -19,7 +19,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFR_6) && !defined(TEST_MPFR_15) && !defined(TEST_MPFR_17) && !defined(TEST_MPFR_30) && !defined(TEST_CPP_DEC_FLOAT_NO_ET) && !defined(TEST_LOGGED_ADAPTER) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_BACKEND #define TEST_MPZ @@ -32,6 +32,7 @@ #define TEST_CPP_DEC_FLOAT_NO_ET #define TEST_LOGGED_ADAPTER #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -60,6 +61,9 @@ #ifdef TEST_LOGGED_ADAPTER #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -115,6 +119,9 @@ void foo() #ifdef TEST_CPP_DEC_FLOAT_NO_ET test_extra(boost::multiprecision::number, boost::multiprecision::et_off>()); #endif +#ifdef TEST_QD + test_extra(boost::multiprecision::quad_double()); +#endif #ifdef TEST_LOGGED_ADAPTER typedef boost::multiprecision::number > > num_t; test_extra(num_t()); diff --git a/test/test_acos.cpp b/test/test_acos.cpp index e165eef67..35f619047 100644 --- a/test/test_acos.cpp +++ b/test/test_acos.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 //# define TEST_MPF #define TEST_BACKEND @@ -24,6 +24,7 @@ #define TEST_MPFI_50 #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template void test() @@ -140,6 +144,9 @@ int main() #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_arithmetic.hpp b/test/test_arithmetic.hpp index 58699fdea..9a643bb24 100644 --- a/test/test_arithmetic.hpp +++ b/test/test_arithmetic.hpp @@ -903,6 +903,18 @@ void test_float_funcs(const boost::mpl::true_&) b = 10; a = pow(a, 10); BOOST_CHECK_EQUAL(a, 1024); + b = 10; + a = -2; + a = pow(a, 10); + BOOST_CHECK_EQUAL(a, 1024); + b = 10; + a = -2; + a = pow(a, b); + BOOST_CHECK_EQUAL(a, 1024); + b = 9; + a = -2; + a = pow(a, b); + BOOST_CHECK_EQUAL(a, -512); a = -2; a = abs(a); BOOST_CHECK_EQUAL(a, 2); diff --git a/test/test_asin.cpp b/test/test_asin.cpp index fc817dce9..d80edd3e6 100644 --- a/test/test_asin.cpp +++ b/test/test_asin.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 //# define TEST_MPF #define TEST_BACKEND @@ -24,6 +24,7 @@ #define TEST_MPFI_50 #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template void test() @@ -135,6 +139,9 @@ int main() #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_atan.cpp b/test/test_atan.cpp index a1c2cbc20..9400ba591 100644 --- a/test/test_atan.cpp +++ b/test/test_atan.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 //# define TEST_MPF #define TEST_BACKEND @@ -24,6 +24,7 @@ #define TEST_MPFI_50 #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif #ifdef BOOST_MSVC #pragma warning(disable : 4127) @@ -288,6 +292,9 @@ int main() #ifdef TEST_FLOAT128 test(); #endif +#ifdef TEST_QD + test(); +#endif #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); diff --git a/test/test_constants.cpp b/test/test_constants.cpp index 206d4530c..2181ad077 100644 --- a/test/test_constants.cpp +++ b/test/test_constants.cpp @@ -9,10 +9,11 @@ #define _SCL_SECURE_NO_WARNINGS #endif -#if !defined(TEST_MPF_50) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) +#if !defined(TEST_MPF_50) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_CPP_DEC_FLOAT #define TEST_MPFR_50 +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -32,6 +33,9 @@ #ifdef TEST_CPP_DEC_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif #include "test.hpp" @@ -192,6 +196,9 @@ int main() #endif #ifdef TEST_MPF_50 test > >(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_cos.cpp b/test/test_cos.cpp index 560dcfb81..8c96d6beb 100644 --- a/test/test_cos.cpp +++ b/test/test_cos.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 //# define TEST_MPF #define TEST_BACKEND @@ -24,6 +24,7 @@ #define TEST_MPFI_50 #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template struct has_poor_large_value_support @@ -377,6 +381,9 @@ int main() #ifdef TEST_FLOAT128 test(); #endif +#ifdef TEST_QD + test(); +#endif #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); diff --git a/test/test_cosh.cpp b/test/test_cosh.cpp index ab9729899..ebaded55a 100644 --- a/test/test_cosh.cpp +++ b/test/test_cosh.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 //# define TEST_MPF #define TEST_BACKEND @@ -24,6 +24,7 @@ #define TEST_MPFI_50 #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template void test() @@ -177,6 +181,9 @@ int main() #ifdef TEST_FLOAT128 test(); #endif +#ifdef TEST_QD + test(); +#endif #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); diff --git a/test/test_exp.cpp b/test/test_exp.cpp index 81c28cebf..1ebf7a55c 100644 --- a/test/test_exp.cpp +++ b/test/test_exp.cpp @@ -17,7 +17,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 //# define TEST_MPF #define TEST_BACKEND @@ -25,6 +25,7 @@ #define TEST_MPFI_50 #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -56,6 +57,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template void test() @@ -198,7 +202,7 @@ void test() BOOST_CHECK_LE(exp(bug_case), (std::numeric_limits::min)()); } } - bug_case = log((std::numeric_limits::max)()) / -1.0005; + bug_case = log((std::numeric_limits::min)()) * -1.0000005; for (unsigned i = 0; i < 20; ++i, bug_case /= 1.05) { BOOST_CHECK_GE(exp(bug_case), (std::numeric_limits::min)()); @@ -244,6 +248,9 @@ int main() #ifdef TEST_FLOAT128 test(); #endif +#ifdef TEST_QD + test(); +#endif #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); diff --git a/test/test_fpclassify.cpp b/test/test_fpclassify.cpp index 2549d0980..40e8147d0 100644 --- a/test/test_fpclassify.cpp +++ b/test/test_fpclassify.cpp @@ -14,7 +14,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_MPFR_50 #define TEST_MPFI_50 @@ -22,6 +22,7 @@ #define TEST_CPP_DEC_FLOAT #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -53,6 +54,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif #ifdef _MSC_VER #pragma warning(disable : 4127) // conditional expression is constant @@ -404,6 +408,9 @@ int main() #ifdef TEST_FLOAT128 test(); #endif +#ifdef TEST_QD + test(); +#endif #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); diff --git a/test/test_hash.cpp b/test/test_hash.cpp index 2572d1ba9..a446a4353 100644 --- a/test/test_hash.cpp +++ b/test/test_hash.cpp @@ -30,6 +30,9 @@ #ifdef TEST_TOMMATH #include #endif +#ifdef TEST_QD +#include +#endif #include @@ -93,6 +96,9 @@ int main() test(); test(); #endif +#ifdef TEST_QD + test(); +#endif return boost::report_errors(); } diff --git a/test/test_log.cpp b/test/test_log.cpp index 8165962d5..66805ee56 100644 --- a/test/test_log.cpp +++ b/test/test_log.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 //# define TEST_MPF #define TEST_BACKEND @@ -24,6 +24,7 @@ #define TEST_MPFR_50 #define TEST_MPFI_50 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template void test() @@ -253,6 +257,9 @@ int main() #ifdef TEST_FLOAT128 test(); #endif +#ifdef TEST_QD + test(); +#endif #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); diff --git a/test/test_numeric_limits.cpp b/test/test_numeric_limits.cpp index 8ec395d00..924779f11 100644 --- a/test/test_numeric_limits.cpp +++ b/test/test_numeric_limits.cpp @@ -11,7 +11,7 @@ #if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && \ !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && \ - !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) + !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_MPF #define TEST_BACKEND @@ -25,6 +25,7 @@ #define TEST_MPFI_50 #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -62,6 +63,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif #ifdef BOOST_MSVC #pragma warning(disable : 4127) @@ -288,6 +292,9 @@ int main() #endif #ifdef TEST_CPP_BIN_FLOAT test(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_pow.cpp b/test/test_pow.cpp index f83a56b03..852a3f666 100644 --- a/test/test_pow.cpp +++ b/test/test_pow.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 //# define TEST_MPF #define TEST_BACKEND @@ -24,6 +24,7 @@ #define TEST_MPFR_50 #define TEST_MPFI_50 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template void test() @@ -778,14 +782,20 @@ void test() unsigned max_err = 0; for (unsigned k = 0; k < data.size(); k++) { - T val = pow(T(data[k][0]), T(data[k][1])); + T base(data[k][0]); + T expon(data[k][1]); + if (base < 0) + if (floor(expon) != expon) + continue; // Reading an integer exponent failed - probably quad_float. + + T val = pow(base, expon); T e = relative_error(val, T(data[k][2])); unsigned err = e.template convert_to(); if (err > max_err) { max_err = err; } - val = pow(T(data[k][0]), -T(data[k][1])); + val = pow(base, -expon); e = relative_error(val, T(1 / T(data[k][2]))); err = e.template convert_to(); if (err > max_err) @@ -865,6 +875,9 @@ int main() #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_round.cpp b/test/test_round.cpp index a582a2120..ea5f8263b 100644 --- a/test/test_round.cpp +++ b/test/test_round.cpp @@ -15,7 +15,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_MPFR_50 #define TEST_MPFI_50 @@ -23,6 +23,7 @@ #define TEST_CPP_DEC_FLOAT #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -54,6 +55,9 @@ #ifdef TEST_FLOAT128 #include #endif +#ifdef TEST_QD +#include +#endif #ifdef BOOST_MSVC #pragma warning(disable : 4127) @@ -464,6 +468,9 @@ int main() #endif #ifdef TEST_FLOAT128 test(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_sin.cpp b/test/test_sin.cpp index 07714f5b6..f24a3ba76 100644 --- a/test/test_sin.cpp +++ b/test/test_sin.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_MPFR_50 #define TEST_MPFI_50 @@ -24,6 +24,7 @@ #define TEST_CPP_DEC_FLOAT #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template struct has_poor_large_value_support @@ -368,6 +372,9 @@ int main() #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_sinh.cpp b/test/test_sinh.cpp index a7f25e349..e9b183ced 100644 --- a/test/test_sinh.cpp +++ b/test/test_sinh.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_MPFR_50 #define TEST_MPFI_50 @@ -24,6 +24,8 @@ #define TEST_CPP_DEC_FLOAT #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +57,12 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif +#ifdef TEST_QD +#include +#endif template void test() @@ -250,9 +258,15 @@ int main() #ifdef TEST_FLOAT128 test(); #endif +#ifdef TEST_QD + test(); +#endif #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_sqrt.cpp b/test/test_sqrt.cpp index 7588c263f..23fe671b8 100644 --- a/test/test_sqrt.cpp +++ b/test/test_sqrt.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_MPFR_50 #define TEST_MPFI_50 @@ -24,6 +24,7 @@ #define TEST_CPP_DEC_FLOAT #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template void test() @@ -234,6 +238,9 @@ int main() #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_tan.cpp b/test/test_tan.cpp index 70b1d68bf..651cbcc59 100644 --- a/test/test_tan.cpp +++ b/test/test_tan.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_MPFI_50 #define TEST_BACKEND @@ -24,6 +24,7 @@ #define TEST_MPFR_50 #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +56,9 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif template struct has_poor_large_value_support @@ -655,6 +659,9 @@ int main() #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } diff --git a/test/test_tanh.cpp b/test/test_tanh.cpp index 85dd54491..891092414 100644 --- a/test/test_tanh.cpp +++ b/test/test_tanh.cpp @@ -16,7 +16,7 @@ #include #include "test.hpp" -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50) && !defined(TEST_FLOAT128) && !defined(TEST_CPP_BIN_FLOAT) && !defined(TEST_QD) && !defined(TEST_QD) #define TEST_MPF_50 #define TEST_MPFR_50 #define TEST_MPFI_50 @@ -24,6 +24,8 @@ #define TEST_CPP_DEC_FLOAT #define TEST_FLOAT128 #define TEST_CPP_BIN_FLOAT +#define TEST_QD +#define TEST_QD #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -55,6 +57,12 @@ #ifdef TEST_CPP_BIN_FLOAT #include #endif +#ifdef TEST_QD +#include +#endif +#ifdef TEST_QD +#include +#endif template void test() @@ -166,9 +174,15 @@ int main() #ifdef TEST_FLOAT128 test(); #endif +#ifdef TEST_QD + test(); +#endif #ifdef TEST_CPP_BIN_FLOAT test(); test, boost::long_long_type> > >(); +#endif +#ifdef TEST_QD + test(); #endif return boost::report_errors(); } From d812df18689276bda33a57bcdb0b149a2bffc49f Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Mon, 2 Mar 2020 14:55:37 +0000 Subject: [PATCH 4/4] mpfr/mpir: Fix numeric_limits<>::round_error(). --- include/boost/multiprecision/mpfi.hpp | 1 - include/boost/multiprecision/mpfr.hpp | 1 - 2 files changed, 2 deletions(-) diff --git a/include/boost/multiprecision/mpfi.hpp b/include/boost/multiprecision/mpfi.hpp index 0bd7c0390..776755a42 100644 --- a/include/boost/multiprecision/mpfi.hpp +++ b/include/boost/multiprecision/mpfi.hpp @@ -1645,7 +1645,6 @@ class numeric_limits