mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-07-21 13:23:49 +00:00
Revert "Revert "Merge pull request #403 from mborland/standalone_fixes""
This reverts commit 04b327b24f.
This commit is contained in:
@@ -125,8 +125,8 @@ class cpp_dec_float
|
||||
private:
|
||||
using array_type =
|
||||
typename std::conditional<std::is_void<Allocator>::value,
|
||||
detail::static_array <std::uint32_t, std::uint32_t(cpp_dec_float_elem_number)>,
|
||||
detail::dynamic_array<std::uint32_t, std::uint32_t(cpp_dec_float_elem_number), Allocator> >::type;
|
||||
detail::static_array <std::uint32_t, static_cast<std::uint32_t>(cpp_dec_float_elem_number)>,
|
||||
detail::dynamic_array<std::uint32_t, static_cast<std::uint32_t>(cpp_dec_float_elem_number), Allocator> >::type;
|
||||
|
||||
typedef enum enum_fpclass_type
|
||||
{
|
||||
@@ -1596,15 +1596,7 @@ double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_double() const
|
||||
: -std::numeric_limits<double>::infinity());
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
|
||||
ss << str(std::numeric_limits<double>::digits10 + (2 + 1), std::ios_base::scientific);
|
||||
|
||||
double d;
|
||||
ss >> d;
|
||||
|
||||
return d;
|
||||
return std::strtod(str(std::numeric_limits<double>::digits10 + (2 + 1), std::ios_base::scientific).c_str(), nullptr);
|
||||
}
|
||||
|
||||
template <unsigned Digits10, class ExponentType, class Allocator>
|
||||
@@ -1643,15 +1635,7 @@ long double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_long_doubl
|
||||
: -std::numeric_limits<long double>::infinity());
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
|
||||
ss << str(std::numeric_limits<long double>::digits10 + (2 + 1), std::ios_base::scientific);
|
||||
|
||||
long double ld;
|
||||
ss >> ld;
|
||||
|
||||
return ld;
|
||||
return std::strtold(str(std::numeric_limits<long double>::digits10 + (2 + 1), std::ios_base::scientific).c_str(), nullptr);
|
||||
}
|
||||
|
||||
template <unsigned Digits10, class ExponentType, class Allocator>
|
||||
@@ -2086,14 +2070,7 @@ bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* con
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
exp = boost::lexical_cast<exponent_type>(static_cast<const char*>(str.c_str() + (pos + 1u)));
|
||||
#else
|
||||
BOOST_IF_CONSTEXPR(std::is_integral<exponent_type>::value)
|
||||
{
|
||||
exp = static_cast<exponent_type>(std::atoll(static_cast<const char*>(str.c_str() + (pos + 1u))));
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Can not use this exponent type in standalone mode. Please de-activate and try again"));
|
||||
}
|
||||
exp = static_cast<exponent_type>(std::atoll(static_cast<const char*>(str.c_str() + (pos + 1u))));
|
||||
#endif
|
||||
|
||||
str = str.substr(static_cast<std::size_t>(0u), pos);
|
||||
@@ -2168,8 +2145,13 @@ bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* con
|
||||
|
||||
if (rit_non_zero != static_cast<std::string::const_reverse_iterator>(str.rbegin()))
|
||||
{
|
||||
const std::string::size_type ofs = static_cast<std::ptrdiff_t>(str.length()) - std::distance<std::string::const_reverse_iterator>(str.rbegin(), rit_non_zero);
|
||||
str.erase(str.begin() + ofs, str.end());
|
||||
const std::string::size_type ofs =
|
||||
static_cast<std::string::size_type>
|
||||
(
|
||||
static_cast<std::ptrdiff_t>(str.length())
|
||||
- std::distance<std::string::const_reverse_iterator>(str.rbegin(), rit_non_zero)
|
||||
);
|
||||
str.erase(str.begin() + static_cast<std::ptrdiff_t>(ofs), str.end());
|
||||
}
|
||||
|
||||
// Check if the input is identically zero.
|
||||
@@ -2191,7 +2173,7 @@ bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* con
|
||||
|
||||
if (str.at(static_cast<std::size_t>(1u)) == static_cast<char>('0'))
|
||||
{
|
||||
delta_exp = std::distance<std::string::const_iterator>(str.begin() + 1u, it_non_zero);
|
||||
delta_exp = static_cast<std::size_t>(std::distance<std::string::const_iterator>(str.begin() + 1u, it_non_zero));
|
||||
}
|
||||
|
||||
// Bring one single digit into the mantissa and adjust the exponent accordingly.
|
||||
@@ -2241,7 +2223,7 @@ bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* con
|
||||
|
||||
// Cut the size of the mantissa to <= cpp_dec_float_elem_digits10.
|
||||
pos = str.find(static_cast<char>('.'));
|
||||
pos_plus_one = static_cast<std::size_t>(pos + 1u);
|
||||
pos_plus_one = static_cast<std::ptrdiff_t>(pos + 1u);
|
||||
|
||||
if (pos > static_cast<std::size_t>(cpp_dec_float_elem_digits10))
|
||||
{
|
||||
@@ -2251,7 +2233,7 @@ bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* con
|
||||
|
||||
str.insert(static_cast<std::size_t>(static_cast<std::int32_t>(n_pos - static_cast<std::int32_t>(n * cpp_dec_float_elem_digits10))), ".");
|
||||
|
||||
str.erase(pos_plus_one, static_cast<std::size_t>(1u));
|
||||
str.erase(static_cast<std::size_t>(pos_plus_one), static_cast<std::size_t>(1u));
|
||||
|
||||
exp += static_cast<exponent_type>(static_cast<exponent_type>(n) * static_cast<exponent_type>(cpp_dec_float_elem_digits10));
|
||||
}
|
||||
@@ -2259,7 +2241,7 @@ bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* con
|
||||
// Pad the decimal part such that its value is an even
|
||||
// multiple of cpp_dec_float_elem_digits10.
|
||||
pos = str.find(static_cast<char>('.'));
|
||||
pos_plus_one = static_cast<std::size_t>(pos + 1u);
|
||||
pos_plus_one = static_cast<std::ptrdiff_t>(pos + 1u);
|
||||
|
||||
// Throws an error for a strange construction like 3.14L
|
||||
if(pos != std::string::npos && (str.back() == 'L' || str.back() == 'l' || str.back() == 'u' || str.back() == 'U'))
|
||||
@@ -2285,7 +2267,7 @@ bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* con
|
||||
if (static_cast<std::size_t>(str.length() - pos) > max_dec)
|
||||
{
|
||||
str = str.substr(static_cast<std::size_t>(0u),
|
||||
static_cast<std::size_t>(pos_plus_one + max_dec));
|
||||
static_cast<std::size_t>(pos_plus_one + static_cast<std::ptrdiff_t>(max_dec)));
|
||||
}
|
||||
|
||||
// Now the input string has the standard cpp_dec_float<Digits10, ExponentType, Allocator> input form.
|
||||
@@ -2300,11 +2282,21 @@ bool cpp_dec_float<Digits10, ExponentType, Allocator>::rd_string(const char* con
|
||||
data[0u] = static_cast<std::uint32_t>(std::stol(str.substr(static_cast<std::size_t>(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<std::string::size_type>(cpp_dec_float_elem_digits10));
|
||||
const std::string::size_type i_end =
|
||||
(
|
||||
static_cast<std::string::size_type>(str.length() - static_cast<std::string::size_type>(pos_plus_one))
|
||||
/ static_cast<std::string::size_type>(cpp_dec_float_elem_digits10)
|
||||
);
|
||||
|
||||
for (std::string::size_type i = static_cast<std::string::size_type>(0u); i < i_end; i++)
|
||||
{
|
||||
const std::string::const_iterator it = str.begin() + pos_plus_one + (i * static_cast<std::string::size_type>(cpp_dec_float_elem_digits10));
|
||||
const std::string::const_iterator it =
|
||||
str.begin()
|
||||
+ static_cast<std::ptrdiff_t>
|
||||
(
|
||||
static_cast<std::string::size_type>(pos_plus_one)
|
||||
+ static_cast<std::string::size_type>(i * static_cast<std::string::size_type>(cpp_dec_float_elem_digits10))
|
||||
);
|
||||
|
||||
data[i + 1u] = static_cast<std::uint32_t>(std::stol(std::string(it, it + static_cast<std::string::size_type>(cpp_dec_float_elem_digits10))));
|
||||
}
|
||||
|
||||
@@ -1270,7 +1270,10 @@ struct cpp_int_base<MinBits, MinBits, unsigned_magnitude, Checked, void, true>
|
||||
{
|
||||
m_data = o.m_data;
|
||||
}
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void negate() noexcept((Checked == unchecked))
|
||||
BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR void negate()
|
||||
#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR)
|
||||
noexcept((Checked == unchecked))
|
||||
#endif
|
||||
{
|
||||
BOOST_IF_CONSTEXPR(Checked == checked)
|
||||
{
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace boost { namespace multiprecision { namespace backends { namespace deta
|
||||
//
|
||||
|
||||
template <typename T>
|
||||
inline constexpr T type_max(T) noexcept
|
||||
inline constexpr T type_max() noexcept
|
||||
{
|
||||
return
|
||||
#ifdef BOOST_HAS_INT128
|
||||
@@ -33,7 +33,7 @@ inline constexpr T type_max(T) noexcept
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline constexpr T type_min(T) noexcept
|
||||
inline constexpr T type_min() noexcept
|
||||
{
|
||||
return
|
||||
#ifdef BOOST_HAS_INT128
|
||||
@@ -69,12 +69,12 @@ inline BOOST_MP_CXX14_CONSTEXPR A checked_add_imp(A a, A b, const std::integral_
|
||||
{
|
||||
if (a > 0)
|
||||
{
|
||||
if ((b > 0) && ((type_max(a) - b) < a))
|
||||
if ((b > 0) && ((type_max<A>() - b) < a))
|
||||
raise_add_overflow();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((b < 0) && ((type_min(a) - b) > a))
|
||||
if ((b < 0) && ((type_min<A>() - b) > a))
|
||||
raise_add_overflow();
|
||||
}
|
||||
return a + b;
|
||||
@@ -82,7 +82,7 @@ inline BOOST_MP_CXX14_CONSTEXPR A checked_add_imp(A a, A b, const std::integral_
|
||||
template <class A>
|
||||
inline BOOST_MP_CXX14_CONSTEXPR A checked_add_imp(A a, A b, const std::integral_constant<bool, false>&)
|
||||
{
|
||||
if ((type_max(a) - b) < a)
|
||||
if ((type_max<A>() - b) < a)
|
||||
raise_add_overflow();
|
||||
return a + b;
|
||||
}
|
||||
@@ -102,12 +102,12 @@ inline BOOST_MP_CXX14_CONSTEXPR A checked_subtract_imp(A a, A b, const std::inte
|
||||
{
|
||||
if (a > 0)
|
||||
{
|
||||
if ((b < 0) && ((type_max(a) + b) < a))
|
||||
if ((b < 0) && ((type_max<A>() + b) < a))
|
||||
raise_subtract_overflow();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((b > 0) && ((type_min(a) + b) > a))
|
||||
if ((b > 0) && ((type_min<A>() + b) > a))
|
||||
raise_subtract_overflow();
|
||||
}
|
||||
return a - b;
|
||||
@@ -134,7 +134,7 @@ template <class A>
|
||||
inline BOOST_MP_CXX14_CONSTEXPR A checked_multiply(A a, A b, const std::integral_constant<int, checked>&)
|
||||
{
|
||||
BOOST_MP_USING_ABS
|
||||
if (a && (type_max(a) / abs(a) < abs(b)))
|
||||
if (a && (type_max<A>() / abs(a) < abs(b)))
|
||||
raise_mul_overflow();
|
||||
return a * b;
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ eval_convert_to(R* result, const cpp_int_backend<MinBits1, MaxBits1, SignType1,
|
||||
}
|
||||
// Perform rounding:
|
||||
bits -= 1 + std::numeric_limits<R>::digits;
|
||||
if (eval_bit_test(backend, (unsigned)bits))
|
||||
if (eval_bit_test(backend, static_cast<unsigned>(bits)))
|
||||
{
|
||||
if ((eval_lsb_imp(backend) < (std::size_t)bits) || eval_bit_test(backend, (std::size_t)(bits + 1)))
|
||||
*result = boost::math::float_next(*result);
|
||||
|
||||
@@ -1004,7 +1004,10 @@ struct terminal
|
||||
template <class Tuple, int i, class T, bool = (i == std::tuple_size<Tuple>::value)>
|
||||
struct find_index_of_type
|
||||
{
|
||||
static constexpr int value = std::is_same<T, typename std::tuple_element<i, Tuple>::type>::value ? i : find_index_of_type<Tuple, i + 1, T>::value;
|
||||
static constexpr int value =
|
||||
std::is_same<T, typename std::tuple_element<static_cast<std::size_t>(i), Tuple>::type>::value
|
||||
? i
|
||||
: find_index_of_type<Tuple, i + 1, T>::value;
|
||||
};
|
||||
template <class Tuple, int i, class T>
|
||||
struct find_index_of_type<Tuple, i, T, true>
|
||||
|
||||
@@ -317,7 +317,7 @@ struct has_enough_bits
|
||||
template <class Tuple, int i, int digits, bool = (i >= std::tuple_size<Tuple>::value)>
|
||||
struct find_index_of_large_enough_type
|
||||
{
|
||||
static constexpr int value = bits_of<typename std::tuple_element<i, Tuple>::type>::value >= digits ? i : find_index_of_large_enough_type<Tuple, i + 1, digits>::value;
|
||||
static constexpr int value = bits_of<typename std::tuple_element<static_cast<std::size_t>(i), Tuple>::type>::value >= digits ? i : find_index_of_large_enough_type<Tuple, i + 1, digits>::value;
|
||||
};
|
||||
template <class Tuple, int i, int digits>
|
||||
struct find_index_of_large_enough_type<Tuple, i, digits, true>
|
||||
@@ -328,7 +328,7 @@ struct find_index_of_large_enough_type<Tuple, i, digits, true>
|
||||
template <int index, class Tuple, class Fallback, bool = (std::tuple_size<Tuple>::value <= index)>
|
||||
struct dereference_tuple
|
||||
{
|
||||
using type = typename std::tuple_element<index, Tuple>::type;
|
||||
using type = typename std::tuple_element<static_cast<std::size_t>(index), Tuple>::type;
|
||||
};
|
||||
template <int index, class Tuple, class Fallback>
|
||||
struct dereference_tuple<index, Tuple, Fallback, true>
|
||||
|
||||
@@ -79,13 +79,13 @@ namespace boost { namespace multiprecision {
|
||||
// Workarounds for numeric limits on old compilers
|
||||
#ifdef BOOST_HAS_INT128
|
||||
# ifndef INT128_MAX
|
||||
# define INT128_MAX (__int128) (((unsigned __int128) 1 << ((__SIZEOF_INT128__ * __CHAR_BIT__) - 1)) - 1)
|
||||
# define INT128_MAX static_cast<boost::multiprecision::int128_type>((static_cast<boost::multiprecision::uint128_type>(1) << ((__SIZEOF_INT128__ * __CHAR_BIT__) - 1)) - 1)
|
||||
# endif
|
||||
# ifndef INT128_MIN
|
||||
# define INT128_MIN (-INT128_MAX - 1)
|
||||
# endif
|
||||
# ifndef UINT128_MAX
|
||||
# define UINT128_MAX ((2 * (unsigned __int128) INT128_MAX) + 1)
|
||||
# define UINT128_MAX ((2 * static_cast<boost::multiprecision::uint128_type>(INT128_MAX)) + 1)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2011 John Maddock. Distributed under the Boost
|
||||
// Copyright 2011 John Maddock.
|
||||
// Copyright 2021 Matt Borland. 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)
|
||||
|
||||
#ifndef BOOST_MATH_ER_GMP_BACKEND_HPP
|
||||
#define BOOST_MATH_ER_GMP_BACKEND_HPP
|
||||
|
||||
#include <boost/multiprecision/detail/standalone_config.hpp>
|
||||
#include <boost/multiprecision/number.hpp>
|
||||
#include <boost/multiprecision/debug_adaptor.hpp>
|
||||
#include <boost/multiprecision/detail/integer_ops.hpp>
|
||||
@@ -15,19 +17,28 @@
|
||||
#include <boost/multiprecision/detail/hash.hpp>
|
||||
#include <boost/multiprecision/detail/no_exceptions_support.hpp>
|
||||
#include <boost/multiprecision/detail/assert.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cstdint>
|
||||
#include <cmath>
|
||||
#include <cctype>
|
||||
#include <limits>
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
|
||||
//
|
||||
// Some includes we need from Boost.Math, since we rely on that library to provide these functions:
|
||||
//
|
||||
#if !defined(BOOST_MP_STANDALONE) || defined(BOOST_MATH_STANDALONE)
|
||||
#include <boost/math/special_functions/asinh.hpp>
|
||||
#include <boost/math/special_functions/acosh.hpp>
|
||||
#include <boost/math/special_functions/atanh.hpp>
|
||||
#include <boost/math/special_functions/cbrt.hpp>
|
||||
#include <boost/math/special_functions/expm1.hpp>
|
||||
#include <boost/math/special_functions/gamma.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
@@ -44,11 +55,6 @@
|
||||
#define BOOST_MP_MPIR_VERSION 0
|
||||
#endif
|
||||
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <climits>
|
||||
|
||||
namespace boost {
|
||||
namespace multiprecision {
|
||||
namespace backends {
|
||||
@@ -294,8 +300,10 @@ struct gmp_float_imp
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_MP_ASSERT(!(boost::math::isinf)(a));
|
||||
BOOST_MP_ASSERT(!(boost::math::isnan)(a));
|
||||
#endif
|
||||
|
||||
int e;
|
||||
F f, term;
|
||||
@@ -1137,6 +1145,34 @@ inline void eval_convert_to(long* result, const gmp_float<digits10>& val) noexce
|
||||
else
|
||||
*result = (long)mpf_get_si(val.data());
|
||||
}
|
||||
#ifdef BOOST_MP_STANDALONE
|
||||
template <unsigned digits10>
|
||||
inline void eval_convert_to(long double* result, const gmp_float<digits10>& val) noexcept
|
||||
{
|
||||
mp_exp_t exp = 0;
|
||||
|
||||
detail::gmp_char_ptr val_char_ptr {mpf_get_str(nullptr, &exp, 10, LDBL_DIG, val.data())};
|
||||
|
||||
auto temp_string = std::string(val_char_ptr.get());
|
||||
if(exp > 0 && static_cast<std::size_t>(exp) < temp_string.size())
|
||||
{
|
||||
if(temp_string.front() == '-')
|
||||
{
|
||||
++exp;
|
||||
}
|
||||
|
||||
temp_string.insert(exp, 1, '.');
|
||||
}
|
||||
|
||||
*result = std::strtold(temp_string.c_str(), nullptr);
|
||||
|
||||
if((temp_string.size() == 2ul && *result < 0.0l) ||
|
||||
(static_cast<std::size_t>(exp) > temp_string.size()))
|
||||
{
|
||||
*result *= std::pow(10l, exp-1);
|
||||
}
|
||||
}
|
||||
#endif // BOOST_MP_STANDALONE
|
||||
template <unsigned digits10>
|
||||
inline void eval_convert_to(double* result, const gmp_float<digits10>& val) noexcept
|
||||
{
|
||||
@@ -1485,8 +1521,10 @@ struct gmp_int
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_MP_ASSERT(!(boost::math::isinf)(a));
|
||||
BOOST_MP_ASSERT(!(boost::math::isnan)(a));
|
||||
#endif
|
||||
|
||||
int e;
|
||||
F f, term;
|
||||
@@ -1951,6 +1989,11 @@ inline void eval_convert_to(long* result, const gmp_int& val)
|
||||
else
|
||||
*result = (signed long)mpz_get_si(val.data());
|
||||
}
|
||||
inline void eval_convert_to(long double* result, const gmp_int& val)
|
||||
{
|
||||
detail::gmp_char_ptr val_char_ptr {mpz_get_str(nullptr, 10, val.data())};
|
||||
*result = std::strtold(val_char_ptr.get(), nullptr);
|
||||
}
|
||||
inline void eval_convert_to(double* result, const gmp_int& val)
|
||||
{
|
||||
*result = mpz_get_d(val.data());
|
||||
@@ -2466,8 +2509,10 @@ struct gmp_rational
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_MP_ASSERT(!(boost::math::isinf)(a));
|
||||
BOOST_MP_ASSERT(!(boost::math::isnan)(a));
|
||||
#endif
|
||||
|
||||
int e;
|
||||
F f, term;
|
||||
@@ -3760,19 +3805,19 @@ namespace Eigen
|
||||
#if !defined(BOOST_MP_STANDALONE) || defined(BOOST_MATH_STANDALONE)
|
||||
static Real epsilon()
|
||||
{
|
||||
return boost::math::tools::epsilon<Real>();
|
||||
return std::numeric_limits<Real>::epsilon();
|
||||
}
|
||||
static Real dummy_precision()
|
||||
static constexpr Real dummy_precision() noexcept
|
||||
{
|
||||
return 1000 * epsilon();
|
||||
}
|
||||
static Real highest()
|
||||
static constexpr Real highest() noexcept
|
||||
{
|
||||
return boost::math::tools::max_value<Real>();
|
||||
return (std::numeric_limits<Real>::max)();
|
||||
}
|
||||
static Real lowest()
|
||||
static constexpr Real lowest() noexcept
|
||||
{
|
||||
return boost::math::tools::min_value<Real>();
|
||||
return (std::numeric_limits<Real>::min)();
|
||||
}
|
||||
static int digits()
|
||||
{
|
||||
@@ -3788,7 +3833,7 @@ namespace Eigen
|
||||
{
|
||||
return LONG_MIN;
|
||||
}
|
||||
static int max_exponent()
|
||||
static constexpr long max_exponent() noexcept
|
||||
{
|
||||
return LONG_MAX;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#include <boost/multiprecision/detail/bitscan.hpp>
|
||||
#include <boost/multiprecision/detail/no_exceptions_support.hpp>
|
||||
#include <boost/multiprecision/detail/standalone_config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace multiprecision {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2011 John Maddock. Distributed under the Boost
|
||||
// Copyright 2011 John Maddock.
|
||||
// Copyright 2021 Matt Borland. 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)
|
||||
|
||||
@@ -12,7 +13,6 @@
|
||||
#include <boost/multiprecision/detail/hash.hpp>
|
||||
#include <boost/multiprecision/detail/no_exceptions_support.hpp>
|
||||
#include <boost/multiprecision/detail/assert.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <cstdint>
|
||||
#include <tommath.h>
|
||||
#include <cctype>
|
||||
@@ -21,6 +21,11 @@
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#if !defined(BOOST_MP_STANDALONE) || defined(BOOST_MATH_STANDALONE)
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace multiprecision {
|
||||
@@ -240,8 +245,10 @@ struct tommath_int
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_MP_STANDALONE) || defined(BOOST_MATH_STANDALONE)
|
||||
BOOST_MP_ASSERT(!(boost::math::isinf)(a));
|
||||
BOOST_MP_ASSERT(!(boost::math::isnan)(a));
|
||||
#endif
|
||||
|
||||
int e;
|
||||
F f, term;
|
||||
|
||||
@@ -1184,8 +1184,6 @@ test-suite standalone :
|
||||
[ run standalone_constexpr_test_cpp_int.cpp : : : [ requires cxx14_constexpr cxx17_if_constexpr ] [ check-target-builds ../config//has_is_constant_evaluated : : <build>no ] ]
|
||||
[ compile standalone_constexpr_test_float128.cpp :
|
||||
[ requires cxx14_constexpr cxx17_if_constexpr ] [ check-target-builds ../config//has_float128 : <source>quadmath : <build>no ] ]
|
||||
|
||||
[ run standalone_test_arithmetic_ab.cpp no_eh_support ]
|
||||
|
||||
[ run standalone_test_arithmetic_complex128.cpp : : : [ check-target-builds ../config//has_float128 : <source>quadmath ] ]
|
||||
[ run standalone_test_arithmetic_cpp_bin_float.cpp no_eh_support : : : <toolset>msvc:<cxxflags>-bigobj ]
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
// 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 "test.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test.hpp"
|
||||
#include "constexpr_arithmetric_test.hpp"
|
||||
#include "boost/multiprecision/cpp_int.hpp"
|
||||
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
// 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 "constexpr_arithmetric_test.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "constexpr_arithmetric_test.hpp"
|
||||
#include <boost/multiprecision/float128.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,21 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
// Copyright 2012 - 2021 John Maddock.
|
||||
// Copyright 2021 Matt Borland. 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 "../performance/arithmetic_backend.hpp"
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
test<boost::multiprecision::number<boost::multiprecision::arithmetic_backend<double>>>();
|
||||
test<boost::multiprecision::number<boost::multiprecision::arithmetic_backend<int>>>();
|
||||
test<boost::multiprecision::number<boost::multiprecision::arithmetic_backend<unsigned>>>();
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -4,15 +4,15 @@
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_FLOAT128
|
||||
#include <boost/multiprecision/complex128.hpp>
|
||||
#endif
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
#include "test_arithmetic.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/cpp_bin_float.hpp>
|
||||
|
||||
template <unsigned Digits, boost::multiprecision::backends::digit_base_type DigitBase, class Allocator, class Exponent, Exponent MinExponent, Exponent MaxExponent, boost::multiprecision::expression_template_option ET>
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/cpp_dec_float.hpp>
|
||||
|
||||
template <unsigned D>
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/float128.hpp>
|
||||
|
||||
int main()
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/gmp.hpp>
|
||||
#include <boost/multiprecision/rational_adaptor.hpp>
|
||||
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
|
||||
template <std::size_t MinBits, std::size_t MaxBits, boost::multiprecision::cpp_integer_type SignType, class Allocator, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/gmp.hpp>
|
||||
#include <boost/multiprecision/logged_adaptor.hpp>
|
||||
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/gmp.hpp>
|
||||
#include <boost/multiprecision/rational_adaptor.hpp>
|
||||
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include "standalone_test_arithmetic.hpp"
|
||||
|
||||
#define BOOST_MP_STANDALONE
|
||||
|
||||
#include "test_arithmetic.hpp"
|
||||
#include <boost/multiprecision/tommath.hpp>
|
||||
|
||||
template <>
|
||||
|
||||
+100
-31
@@ -7,12 +7,17 @@
|
||||
#include <vld.h>
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
#include <numeric>
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include "test.hpp"
|
||||
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
#include <boost/math/special_functions/pow.hpp>
|
||||
#include <boost/integer/common_factor_rt.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <functional>
|
||||
#include "test.hpp"
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct is_boost_rational : public std::integral_constant<bool, false>
|
||||
@@ -73,6 +78,7 @@ Target checked_lexical_cast(const Source& val)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif // BOOST_MP_STANDALONE
|
||||
|
||||
bool isfloat(float) { return true; }
|
||||
bool isfloat(double) { return true; }
|
||||
@@ -300,7 +306,7 @@ void test_complement(Real a, Real b, Real c, const std::integral_constant<bool,
|
||||
int i = 1020304;
|
||||
int j = 56789123;
|
||||
int sign_mask = ~0;
|
||||
if (std::numeric_limits<Real>::is_signed)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_signed)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(~a, (~i & sign_mask));
|
||||
c = a & ~b;
|
||||
@@ -460,10 +466,18 @@ void test_signed_integer_ops(const std::integral_constant<bool, true>&)
|
||||
#endif
|
||||
a = 400;
|
||||
b = 45;
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_CHECK_EQUAL(gcd(a, -45), boost::integer::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, -45), boost::integer::lcm(400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(-400, b), boost::integer::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(-400, b), boost::integer::lcm(400, 45));
|
||||
#elif __cpp_lib_gcd_lcm >= 201606L
|
||||
BOOST_CHECK_EQUAL(gcd(a, -45), std::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, -45), std::lcm(400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(-400, b), std::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(-400, b), std::lcm(400, 45));
|
||||
#endif
|
||||
|
||||
a = -20;
|
||||
BOOST_CHECK_EQUAL(abs(a), 20);
|
||||
BOOST_CHECK_EQUAL(abs(-a), 20);
|
||||
@@ -474,12 +488,22 @@ void test_signed_integer_ops(const std::integral_constant<bool, true>&)
|
||||
BOOST_CHECK_EQUAL(abs(+a), 20);
|
||||
a = -400;
|
||||
b = 45;
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_CHECK_EQUAL(gcd(a, b), boost::integer::gcd(-400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, b), boost::integer::lcm(-400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(a, 45), boost::integer::gcd(-400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, 45), boost::integer::lcm(-400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(-400, b), boost::integer::gcd(-400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(-400, b), boost::integer::lcm(-400, 45));
|
||||
#elif __cpp_lib_gcd_lcm >= 201606L
|
||||
BOOST_CHECK_EQUAL(gcd(a, b), std::gcd(-400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, b), std::lcm(-400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(a, 45), std::gcd(-400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, 45), std::lcm(-400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(-400, b), std::gcd(-400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(-400, b), std::lcm(-400, 45));
|
||||
#endif
|
||||
|
||||
Real r;
|
||||
divide_qr(a, b, c, r);
|
||||
BOOST_CHECK_EQUAL(c, a / b);
|
||||
@@ -538,7 +562,7 @@ inline Real negate_if_signed(Real r, const std::integral_constant<bool, false>&)
|
||||
template <class Real, class Int>
|
||||
void test_integer_overflow()
|
||||
{
|
||||
if (std::numeric_limits<Real>::digits > std::numeric_limits<Int>::digits)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::digits > std::numeric_limits<Int>::digits)
|
||||
{
|
||||
Real m((std::numeric_limits<Int>::max)());
|
||||
Int r;
|
||||
@@ -575,7 +599,7 @@ void test_integer_overflow()
|
||||
BOOST_CHECK_EQUAL(r, 0);
|
||||
}
|
||||
|
||||
if (std::numeric_limits<Real>::is_signed && (boost::multiprecision::detail::is_signed<Int>::value))
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_signed && (boost::multiprecision::detail::is_signed<Int>::value))
|
||||
{
|
||||
m = (std::numeric_limits<Int>::min)();
|
||||
--m;
|
||||
@@ -603,9 +627,10 @@ void test_integer_overflow()
|
||||
BOOST_CHECK_EQUAL(r, (std::numeric_limits<Int>::min)());
|
||||
}
|
||||
}
|
||||
else if (std::numeric_limits<Real>::is_signed && !boost::multiprecision::detail::is_signed<Int>::value)
|
||||
else BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_signed && !boost::multiprecision::detail::is_signed<Int>::value)
|
||||
{
|
||||
// signed to unsigned converison with overflow, it's really not clear what should happen here!
|
||||
#if 0
|
||||
m = (std::numeric_limits<Int>::max)();
|
||||
++m;
|
||||
m = negate_if_signed(m, std::integral_constant<bool, std::numeric_limits<Real>::is_signed>());
|
||||
@@ -615,6 +640,7 @@ void test_integer_overflow()
|
||||
m = pow(m, (std::min)(std::numeric_limits<Real>::digits - 1, 1000));
|
||||
m = negate_if_signed(m, std::integral_constant<bool, std::numeric_limits<Real>::is_signed>());
|
||||
BOOST_CHECK_THROW(m.template convert_to<Int>(), std::range_error);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -622,12 +648,12 @@ void test_integer_overflow()
|
||||
template <class Real, class Int>
|
||||
void test_integer_round_trip()
|
||||
{
|
||||
if (std::numeric_limits<Real>::digits >= std::numeric_limits<Int>::digits)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::digits >= std::numeric_limits<Int>::digits)
|
||||
{
|
||||
Real m((std::numeric_limits<Int>::max)());
|
||||
Int r = m.template convert_to<Int>();
|
||||
BOOST_CHECK_EQUAL(m, r);
|
||||
if (std::numeric_limits<Real>::is_signed && (std::numeric_limits<Real>::digits > std::numeric_limits<Int>::digits))
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_signed && (std::numeric_limits<Real>::digits > std::numeric_limits<Int>::digits))
|
||||
{
|
||||
m = (std::numeric_limits<Int>::min)();
|
||||
r = m.template convert_to<Int>();
|
||||
@@ -834,6 +860,7 @@ void test_integer_ops(const std::integral_constant<int, boost::multiprecision::n
|
||||
//
|
||||
a = 400;
|
||||
b = 45;
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_CHECK_EQUAL(gcd(a, b), boost::integer::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, b), boost::integer::lcm(400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(a, 45), boost::integer::gcd(400, 45));
|
||||
@@ -844,8 +871,20 @@ void test_integer_ops(const std::integral_constant<int, boost::multiprecision::n
|
||||
BOOST_CHECK_EQUAL(lcm(400, b), boost::integer::lcm(400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(400u, b), boost::integer::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(400u, b), boost::integer::lcm(400, 45));
|
||||
#elif __cpp_lib_gcd_lcm >= 201606L
|
||||
BOOST_CHECK_EQUAL(gcd(a, b), std::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, b), std::lcm(400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(a, 45), std::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, 45), std::lcm(400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(a, 45u), std::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(a, 45u), std::lcm(400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(400, b), std::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(400, b), std::lcm(400, 45));
|
||||
BOOST_CHECK_EQUAL(gcd(400u, b), std::gcd(400, 45));
|
||||
BOOST_CHECK_EQUAL(lcm(400u, b), std::lcm(400, 45));
|
||||
#endif
|
||||
|
||||
if (std::numeric_limits<Real>::is_bounded)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_bounded)
|
||||
{
|
||||
// Fixed precision integer:
|
||||
a = (std::numeric_limits<Real>::max)() - 1;
|
||||
@@ -1181,7 +1220,7 @@ void test_float_funcs(const std::integral_constant<bool, true>&)
|
||||
BOOST_CHECK_EQUAL(b > 0, a > 0);
|
||||
BOOST_CHECK_EQUAL(c > 0, a > 0);
|
||||
|
||||
if (std::numeric_limits<Real>::has_infinity)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_infinity)
|
||||
{
|
||||
a = std::numeric_limits<Real>::infinity();
|
||||
b = modf(a, &c);
|
||||
@@ -1192,12 +1231,14 @@ void test_float_funcs(const std::integral_constant<bool, true>&)
|
||||
BOOST_CHECK_EQUAL(a, c);
|
||||
BOOST_CHECK_EQUAL(b, 0);
|
||||
}
|
||||
if (std::numeric_limits<Real>::has_quiet_NaN)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_quiet_NaN)
|
||||
{
|
||||
a = std::numeric_limits<Real>::quiet_NaN();
|
||||
b = modf(a, &c);
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_CHECK((boost::math::isnan)(b));
|
||||
BOOST_CHECK((boost::math::isnan)(c));
|
||||
#endif
|
||||
}
|
||||
|
||||
a = 4;
|
||||
@@ -1328,7 +1369,7 @@ void test_float_ops(const std::integral_constant<int, boost::multiprecision::num
|
||||
// scalbn and logb, these are the same as ldexp and frexp unless the radix is
|
||||
// something other than 2:
|
||||
//
|
||||
if (std::numeric_limits<Real>::is_specialized && std::numeric_limits<Real>::radix)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_specialized && std::numeric_limits<Real>::radix)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(scalbn(Real(2), 5), 2 * pow(double(std::numeric_limits<Real>::radix), 5));
|
||||
BOOST_CHECK_EQUAL(scalbn(Real(2), -5), Real(2) / pow(double(std::numeric_limits<Real>::radix), 5));
|
||||
@@ -1350,6 +1391,7 @@ void test_float_ops(const std::integral_constant<int, boost::multiprecision::num
|
||||
//
|
||||
// pow and exponent:
|
||||
//
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
v = 3.25;
|
||||
r = pow(v, 0);
|
||||
BOOST_CHECK_EQUAL(r, 1);
|
||||
@@ -1367,17 +1409,20 @@ void test_float_ops(const std::integral_constant<int, boost::multiprecision::num
|
||||
BOOST_CHECK_EQUAL(r, boost::math::pow<6>(3.25));
|
||||
r = pow(v, 25);
|
||||
BOOST_CHECK_EQUAL(r, boost::math::pow<25>(Real(3.25)));
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
//
|
||||
// Things that are expected errors:
|
||||
//
|
||||
BOOST_CHECK_THROW(Real("3.14L"), std::runtime_error);
|
||||
if (std::numeric_limits<Real>::is_specialized)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_specialized)
|
||||
{
|
||||
if (std::numeric_limits<Real>::has_infinity)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_infinity)
|
||||
{
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_CHECK((boost::math::isinf)(Real(20) / 0u));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1388,7 +1433,7 @@ void test_float_ops(const std::integral_constant<int, boost::multiprecision::num
|
||||
//
|
||||
// Comparisons of NaN's should always fail:
|
||||
//
|
||||
if (std::numeric_limits<Real>::has_quiet_NaN)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_quiet_NaN)
|
||||
{
|
||||
r = v = std::numeric_limits<Real>::quiet_NaN();
|
||||
compare_NaNs(r, v);
|
||||
@@ -1406,7 +1451,7 @@ void test_float_ops(const std::integral_constant<int, boost::multiprecision::num
|
||||
//
|
||||
compare_NaNs(v, 0.5);
|
||||
compare_NaNs(0.5, v);
|
||||
if (std::numeric_limits<double>::has_quiet_NaN)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<double>::has_quiet_NaN)
|
||||
{
|
||||
compare_NaNs(r, std::numeric_limits<double>::quiet_NaN());
|
||||
compare_NaNs(std::numeric_limits<double>::quiet_NaN(), r);
|
||||
@@ -1416,8 +1461,9 @@ void test_float_ops(const std::integral_constant<int, boost::multiprecision::num
|
||||
//
|
||||
// Operations involving NaN's as one argument:
|
||||
//
|
||||
if (std::numeric_limits<Real>::has_quiet_NaN)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_quiet_NaN)
|
||||
{
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
v = 20.25;
|
||||
r = std::numeric_limits<Real>::quiet_NaN();
|
||||
BOOST_CHECK((boost::math::isnan)(v + r));
|
||||
@@ -1444,23 +1490,29 @@ void test_float_ops(const std::integral_constant<int, boost::multiprecision::num
|
||||
BOOST_CHECK((boost::math::isnan)(t /= v));
|
||||
t = v;
|
||||
BOOST_CHECK((boost::math::isnan)(t /= r));
|
||||
#endif
|
||||
}
|
||||
//
|
||||
// Operations involving infinities as one argument:
|
||||
//
|
||||
if (std::numeric_limits<Real>::has_infinity)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_infinity)
|
||||
{
|
||||
v = 20.25;
|
||||
r = std::numeric_limits<Real>::infinity();
|
||||
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_CHECK((boost::math::isinf)(v + r));
|
||||
BOOST_CHECK((boost::math::isinf)(r + v));
|
||||
BOOST_CHECK((boost::math::isinf)(r - v));
|
||||
BOOST_CHECK((boost::math::isinf)(v - r));
|
||||
BOOST_CHECK_LT(v - r, 0);
|
||||
BOOST_CHECK((boost::math::isinf)(r * v));
|
||||
BOOST_CHECK((boost::math::isinf)(v * r));
|
||||
BOOST_CHECK((boost::math::isinf)(r / v));
|
||||
#endif
|
||||
|
||||
BOOST_CHECK_LT(v - r, 0);
|
||||
BOOST_CHECK_EQUAL(v / r, 0);
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
Real t = v;
|
||||
BOOST_CHECK((boost::math::isinf)(t += r));
|
||||
t = r;
|
||||
@@ -1479,21 +1531,27 @@ void test_float_ops(const std::integral_constant<int, boost::multiprecision::num
|
||||
BOOST_CHECK((boost::math::isinf)(t /= v));
|
||||
t = v;
|
||||
BOOST_CHECK((t /= r) == 0);
|
||||
#endif
|
||||
}
|
||||
//
|
||||
// Operations that should produce NaN as a result:
|
||||
//
|
||||
if (std::numeric_limits<Real>::has_quiet_NaN)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_quiet_NaN)
|
||||
{
|
||||
v = r = 0;
|
||||
Real t = v / r;
|
||||
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
BOOST_CHECK((boost::math::isnan)(t));
|
||||
v /= r;
|
||||
BOOST_CHECK((boost::math::isnan)(v));
|
||||
t = v / 0;
|
||||
BOOST_CHECK((boost::math::isnan)(v));
|
||||
if (std::numeric_limits<Real>::has_infinity)
|
||||
#endif
|
||||
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_infinity)
|
||||
{
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
v = 0;
|
||||
r = std::numeric_limits<Real>::infinity();
|
||||
t = v * r;
|
||||
@@ -1506,6 +1564,7 @@ void test_float_ops(const std::integral_constant<int, boost::multiprecision::num
|
||||
v = r;
|
||||
t = r / v;
|
||||
BOOST_CHECK((boost::math::isnan)(t));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1559,6 +1618,7 @@ void test_negative_mixed_minmax(std::integral_constant<bool, false> const&)
|
||||
template <class Real, class Num>
|
||||
void test_negative_mixed_numeric_limits(std::integral_constant<bool, true> const&)
|
||||
{
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
typedef typename lexical_cast_target_type<Num>::type target_type;
|
||||
#if defined(TEST_MPFR)
|
||||
Num tol = 10 * std::numeric_limits<Num>::epsilon();
|
||||
@@ -1574,13 +1634,14 @@ void test_negative_mixed_numeric_limits(std::integral_constant<bool, true> const
|
||||
int digits_to_print = std::is_floating_point<Num>::value && std::numeric_limits<Num>::is_specialized
|
||||
? std::numeric_limits<Num>::digits10 + 5
|
||||
: 0;
|
||||
if (std::numeric_limits<target_type>::digits <= std::numeric_limits<Real>::digits)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<target_type>::digits <= std::numeric_limits<Real>::digits)
|
||||
{
|
||||
BOOST_CHECK_CLOSE(n1, checked_lexical_cast<target_type>(Real(n1).str(digits_to_print, f)), tol);
|
||||
}
|
||||
BOOST_CHECK_CLOSE(n2, checked_lexical_cast<target_type>(Real(n2).str(digits_to_print, f)), 0);
|
||||
BOOST_CHECK_CLOSE(n3, checked_lexical_cast<target_type>(Real(n3).str(digits_to_print, f)), 0);
|
||||
BOOST_CHECK_CLOSE(n4, checked_lexical_cast<target_type>(Real(n4).str(digits_to_print, f)), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class Real, class Num>
|
||||
@@ -1892,7 +1953,11 @@ void test_mixed(const std::integral_constant<bool, false>&)
|
||||
template <class Real>
|
||||
inline bool check_is_nan(const Real& val, const std::integral_constant<bool, true>&)
|
||||
{
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
return (boost::math::isnan)(val);
|
||||
#else
|
||||
return true; // Avoids warnings. This functionality is never used in standalone mode
|
||||
#endif
|
||||
}
|
||||
template <class Real>
|
||||
inline bool check_is_nan(const Real&, const std::integral_constant<bool, false>&)
|
||||
@@ -1913,6 +1978,7 @@ inline Real negate_value(const Real& val, const std::integral_constant<bool, fal
|
||||
template <class Real, class Num>
|
||||
void test_mixed_numeric_limits(const std::integral_constant<bool, true>&)
|
||||
{
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
typedef typename lexical_cast_target_type<Num>::type target_type;
|
||||
#if defined(TEST_MPFR)
|
||||
Num tol = 10 * std::numeric_limits<Num>::epsilon();
|
||||
@@ -1921,19 +1987,21 @@ void test_mixed_numeric_limits(const std::integral_constant<bool, true>&)
|
||||
#endif
|
||||
|
||||
Real d;
|
||||
if (std::numeric_limits<Real>::has_infinity && std::numeric_limits<Num>::has_infinity)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_infinity && std::numeric_limits<Num>::has_infinity)
|
||||
{
|
||||
d = static_cast<Real>(std::numeric_limits<Num>::infinity());
|
||||
BOOST_CHECK_GT(d, (std::numeric_limits<Real>::max)());
|
||||
d = static_cast<Real>(negate_value(std::numeric_limits<Num>::infinity(), std::integral_constant<bool, std::numeric_limits<Num>::is_signed>()));
|
||||
BOOST_CHECK_LT(d, negate_value((std::numeric_limits<Real>::max)(), std::integral_constant<bool, std::numeric_limits<Real>::is_signed>()));
|
||||
}
|
||||
if (std::numeric_limits<Real>::has_quiet_NaN && std::numeric_limits<Num>::has_quiet_NaN)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::has_quiet_NaN && std::numeric_limits<Num>::has_quiet_NaN)
|
||||
{
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
d = static_cast<Real>(std::numeric_limits<Num>::quiet_NaN());
|
||||
BOOST_CHECK(check_is_nan(d, std::integral_constant<bool, std::numeric_limits<Real>::has_quiet_NaN>()));
|
||||
d = static_cast<Real>(negate_value(std::numeric_limits<Num>::quiet_NaN(), std::integral_constant<bool, std::numeric_limits<Num>::is_signed>()));
|
||||
BOOST_CHECK(check_is_nan(d, std::integral_constant<bool, std::numeric_limits<Real>::has_quiet_NaN>()));
|
||||
#endif
|
||||
}
|
||||
|
||||
static const int left_shift = std::numeric_limits<Num>::digits - 1;
|
||||
@@ -1946,13 +2014,14 @@ void test_mixed_numeric_limits(const std::integral_constant<bool, true>&)
|
||||
int digits_to_print = std::is_floating_point<Num>::value && std::numeric_limits<Num>::is_specialized
|
||||
? std::numeric_limits<Num>::digits10 + 5
|
||||
: 0;
|
||||
if (std::numeric_limits<target_type>::digits <= std::numeric_limits<Real>::digits)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<target_type>::digits <= std::numeric_limits<Real>::digits)
|
||||
{
|
||||
BOOST_CHECK_CLOSE(n1, checked_lexical_cast<target_type>(Real(n1).str(digits_to_print, f)), tol);
|
||||
}
|
||||
BOOST_CHECK_CLOSE(n2, checked_lexical_cast<target_type>(Real(n2).str(digits_to_print, f)), 0);
|
||||
BOOST_CHECK_CLOSE(n3, checked_lexical_cast<target_type>(Real(n3).str(digits_to_print, f)), 0);
|
||||
BOOST_CHECK_CLOSE(n4, checked_lexical_cast<target_type>(Real(n4).str(digits_to_print, f)), 0);
|
||||
#endif // BOOST_MP_STANDALONE
|
||||
}
|
||||
template <class Real, class Num>
|
||||
void test_mixed_numeric_limits(const std::integral_constant<bool, false>&)
|
||||
@@ -1982,7 +2051,7 @@ void test_mixed(const std::integral_constant<bool, true>&)
|
||||
Num,
|
||||
Real>::type simple_cast_type;
|
||||
|
||||
if (std::numeric_limits<Real>::is_specialized && std::numeric_limits<Real>::is_bounded && std::numeric_limits<Real>::digits < std::numeric_limits<Num>::digits)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_specialized && std::numeric_limits<Real>::is_bounded && std::numeric_limits<Real>::digits < std::numeric_limits<Num>::digits)
|
||||
return;
|
||||
|
||||
std::cout << "Testing mixed arithmetic with type: " << name_of<Real>() << " and " << name_of<Num>() << std::endl;
|
||||
@@ -2594,7 +2663,7 @@ typename std::enable_if<boost::multiprecision::number_category<Real>::value != b
|
||||
Real b = 30;
|
||||
BOOST_CHECK(a.sign() > 0);
|
||||
BOOST_CHECK(!a.is_zero());
|
||||
if (std::numeric_limits<Real>::is_signed)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_signed)
|
||||
{
|
||||
a = -20;
|
||||
BOOST_CHECK(a.sign() < 0);
|
||||
@@ -3081,7 +3150,7 @@ void test()
|
||||
ac -= +a;
|
||||
BOOST_CHECK_EQUAL(ac, 0);
|
||||
ac = a;
|
||||
if (std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
|
||||
{
|
||||
ac = a;
|
||||
ac -= c - b;
|
||||
@@ -3093,7 +3162,7 @@ void test()
|
||||
ac = a;
|
||||
ac += ac * b;
|
||||
BOOST_CHECK_EQUAL(ac, 8 + 8 * 64);
|
||||
if (std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
|
||||
BOOST_IF_CONSTEXPR (std::numeric_limits<Real>::is_signed || is_twos_complement_integer<Real>::value)
|
||||
{
|
||||
ac = a;
|
||||
ac -= ac * b;
|
||||
@@ -3252,7 +3321,7 @@ void test()
|
||||
//
|
||||
// Test hashing:
|
||||
//
|
||||
boost::hash<Real> hasher;
|
||||
std::hash<Real> hasher;
|
||||
std::size_t s = hasher(a);
|
||||
BOOST_CHECK_NE(s, 0);
|
||||
std::hash<Real> hasher2;
|
||||
|
||||
Reference in New Issue
Block a user