Updated boost multiprecision, and disabled deprecated declarations warning
This commit is contained in:
parent
9f739ada6a
commit
6bc7069099
31 changed files with 3656 additions and 83 deletions
|
|
@ -177,4 +177,9 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if _LIBCPP_VERSION <= 170006
|
||||
// no std::ranges::join_view
|
||||
# define BOOST_NO_CXX20_HDR_RANGES
|
||||
#endif
|
||||
|
||||
// --- end ---
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
////////////////////////////////////////////////////////////////
|
||||
// Copyright 2013 - 2022 John Maddock.
|
||||
// Copyright 2022 Christopher Kormanyos.
|
||||
// Copyright 2013 - 2025 John Maddock.
|
||||
// Copyright 2022 - 2025 Christopher Kormanyos.
|
||||
// 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)
|
||||
|
|
@ -1614,6 +1614,10 @@ inline void convert_to_unsigned_int(I* res, const cpp_bin_float<Digits, DigitBas
|
|||
return;
|
||||
case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_nan:
|
||||
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Could not convert NaN to integer."));
|
||||
#if defined(BOOST_NO_EXCEPTIONS)
|
||||
*res = max_val;
|
||||
return;
|
||||
#endif
|
||||
case cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_infinity:
|
||||
*res = max_val;
|
||||
return;
|
||||
|
|
@ -1622,15 +1626,34 @@ inline void convert_to_unsigned_int(I* res, const cpp_bin_float<Digits, DigitBas
|
|||
}
|
||||
typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::rep_type man(arg.bits());
|
||||
using shift_type = typename std::conditional<sizeof(typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type) < sizeof(int), int, typename cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::exponent_type>::type;
|
||||
shift_type shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
|
||||
if (shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
|
||||
|
||||
const shift_type shift = (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - arg.exponent();
|
||||
|
||||
if (arg.sign())
|
||||
{
|
||||
using si_type = typename boost::multiprecision::detail::make_signed<I>::type;
|
||||
|
||||
si_type val;
|
||||
|
||||
convert_to_signed_int(&val, arg);
|
||||
|
||||
*res = static_cast<I>(val);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (shift > (shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1)
|
||||
{
|
||||
*res = 0;
|
||||
return;
|
||||
}
|
||||
else if (arg.compare(max_val) >= 0)
|
||||
{
|
||||
*res = max_val;
|
||||
return;
|
||||
}
|
||||
else if (shift < 0)
|
||||
{
|
||||
if (cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - shift <= digits)
|
||||
if ((shift_type)cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - shift <= (shift_type)digits)
|
||||
{
|
||||
// We have more bits in ulong_long_type than the float, so it's OK to left shift:
|
||||
eval_convert_to(res, man);
|
||||
|
|
@ -1640,7 +1663,7 @@ inline void convert_to_unsigned_int(I* res, const cpp_bin_float<Digits, DigitBas
|
|||
*res = max_val;
|
||||
return;
|
||||
}
|
||||
eval_right_shift(man, shift);
|
||||
eval_right_shift(man, static_cast<unsigned>(shift));
|
||||
eval_convert_to(res, man);
|
||||
}
|
||||
|
||||
|
|
@ -2031,18 +2054,18 @@ inline void eval_ceil(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE
|
|||
}
|
||||
bool fractional = (shift_type)eval_lsb(arg.bits()) < shift;
|
||||
res = arg;
|
||||
eval_right_shift(res.bits(), shift);
|
||||
eval_right_shift(res.bits(), static_cast<unsigned>(shift));
|
||||
if (fractional && !res.sign())
|
||||
{
|
||||
eval_increment(res.bits());
|
||||
if ((std::ptrdiff_t)eval_msb(res.bits()) != cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count - 1 - shift)
|
||||
if ((std::ptrdiff_t)eval_msb(res.bits()) != (std::ptrdiff_t)(static_cast<shift_type>(cpp_bin_float<Digits, DigitBase, Allocator, Exponent, MinE, MaxE>::bit_count) - 1 - shift))
|
||||
{
|
||||
// Must have extended result by one bit in the increment:
|
||||
--shift;
|
||||
++res.exponent();
|
||||
}
|
||||
}
|
||||
eval_left_shift(res.bits(), shift);
|
||||
eval_left_shift(res.bits(), static_cast<unsigned>(shift));
|
||||
}
|
||||
|
||||
template <unsigned D1, backends::digit_base_type B1, class A1, class E1, E1 M1, E1 M2>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2002 - 2021.
|
||||
// Copyright 2011 -2021 John Maddock. Distributed under the Boost
|
||||
// Copyright Christopher Kormanyos 2002 - 2025.
|
||||
// Copyright 2011 -2025 John Maddock. Distributed under the Boost
|
||||
// Software License, Version 1.0. (See accompanying file
|
||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
|
@ -163,7 +163,7 @@ class cpp_dec_float
|
|||
a.prec_elem = cpp_dec_float_elem_number;
|
||||
|
||||
return a;
|
||||
}
|
||||
} // LCOV_EXCL_LINE
|
||||
|
||||
public:
|
||||
// Public Constructors
|
||||
|
|
@ -501,7 +501,9 @@ class cpp_dec_float
|
|||
|
||||
prec_elem = (std::min)(cpp_dec_float_elem_number, (std::max)(elems, static_cast<std::int32_t>(2)));
|
||||
}
|
||||
|
||||
static cpp_dec_float pow2(long long i);
|
||||
|
||||
exponent_type order() const
|
||||
{
|
||||
const bool bo_order_is_zero = ((!(isfinite)()) || (data[0] == static_cast<std::uint32_t>(0u)));
|
||||
|
|
@ -515,12 +517,7 @@ class cpp_dec_float
|
|||
if (data[0] >= 10000000UL)
|
||||
{
|
||||
if (data[0] >= 100000000UL)
|
||||
{
|
||||
if (data[0] >= 1000000000UL)
|
||||
prefix = 9;
|
||||
else
|
||||
prefix = 8;
|
||||
}
|
||||
prefix = 8;
|
||||
else
|
||||
prefix = 7;
|
||||
}
|
||||
|
|
@ -1164,7 +1161,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone
|
|||
else
|
||||
{
|
||||
*this = inf();
|
||||
if (isneg())
|
||||
if (b_neg)
|
||||
negate();
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1181,7 +1178,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator>& cpp_dec_float<Digits10, Expone
|
|||
cpp_dec_float t;
|
||||
t = n;
|
||||
return operator/=(t);
|
||||
}
|
||||
} // LCOV_EXCL_LINE
|
||||
|
||||
const std::uint32_t nn = static_cast<std::uint32_t>(n);
|
||||
|
||||
|
|
@ -1645,7 +1642,7 @@ long double cpp_dec_float<Digits10, ExponentType, Allocator>::extract_long_doubl
|
|||
// Check if *this cpp_dec_float<Digits10, ExponentType, Allocator> exceeds the maximum of double.
|
||||
if (xx.compare(long_double_max()) > 0)
|
||||
{
|
||||
return ((!neg) ? std::numeric_limits<long double>::infinity()
|
||||
return ((!neg) ? std::numeric_limits<long double>::infinity()
|
||||
: -std::numeric_limits<long double>::infinity());
|
||||
}
|
||||
|
||||
|
|
@ -1713,7 +1710,7 @@ long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_long_
|
|||
// See https://svn.boost.org/trac/boost/ticket/9740.
|
||||
//
|
||||
long long sval = static_cast<long long>(val - 1);
|
||||
sval = -sval;
|
||||
sval = -sval;
|
||||
--sval;
|
||||
return sval;
|
||||
}
|
||||
|
|
@ -1749,14 +1746,14 @@ unsigned long long cpp_dec_float<Digits10, ExponentType, Allocator>::extract_uns
|
|||
else
|
||||
{
|
||||
// Extract the data into an unsigned long long value.
|
||||
val = static_cast<unsigned long long>(xn.data[0]);
|
||||
val = static_cast<unsigned long long>(xn.data[std::size_t { 0U }]);
|
||||
|
||||
const std::int32_t imax = (std::min)(static_cast<std::int32_t>(static_cast<std::int32_t>(xn.exp) / cpp_dec_float_elem_digits10), static_cast<std::int32_t>(cpp_dec_float_elem_number - static_cast<std::int32_t>(1)));
|
||||
|
||||
for (std::int32_t i = static_cast<std::int32_t>(1); i <= imax; i++)
|
||||
{
|
||||
val *= static_cast<unsigned long long>(cpp_dec_float_elem_mask);
|
||||
val += static_cast<unsigned long long>(xn.data[i]);
|
||||
val += static_cast<unsigned long long>(xn.data[static_cast<std::size_t>(i)]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1795,7 +1792,7 @@ int128_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_int
|
|||
}
|
||||
else
|
||||
{
|
||||
// Extract the data into an unsigned long long value.
|
||||
// Extract the data into an (unsigned) boost::uint128_type value.
|
||||
cpp_dec_float<Digits10, ExponentType, Allocator> xn(extract_integer_part());
|
||||
if (xn.isneg())
|
||||
xn.negate();
|
||||
|
|
@ -1817,9 +1814,9 @@ int128_type cpp_dec_float<Digits10, ExponentType, Allocator>::extract_signed_int
|
|||
}
|
||||
else
|
||||
{
|
||||
// This strange expression avoids a hardware trap in the corner case
|
||||
// that val is the most negative value permitted in long long.
|
||||
// See https://svn.boost.org/trac/boost/ticket/9740.
|
||||
// This strange expression avoids a hardware trap in the corner case that
|
||||
// val is the most negative value permitted in (signed) boost::int128_type.
|
||||
// See also https://svn.boost.org/trac/boost/ticket/9740.
|
||||
//
|
||||
int128_type sval = static_cast<int128_type>(val - 1);
|
||||
sval = -sval;
|
||||
|
|
@ -3157,7 +3154,7 @@ cpp_dec_float<Digits10, ExponentType, Allocator> cpp_dec_float<Digits10, Exponen
|
|||
default_ops::detail::pow_imp(t, cpp_dec_float<Digits10, ExponentType, Allocator>::two(), static_cast<unsigned long long>(p), std::integral_constant<bool, false>());
|
||||
|
||||
return t;
|
||||
}
|
||||
} // LCOV_EXCL_LINE
|
||||
|
||||
template <unsigned Digits10, class ExponentType, class Allocator>
|
||||
inline void eval_add(cpp_dec_float<Digits10, ExponentType, Allocator>& result, const cpp_dec_float<Digits10, ExponentType, Allocator>& o)
|
||||
|
|
@ -3592,7 +3589,7 @@ class numeric_limits<boost::multiprecision::number<boost::multiprecision::cpp_de
|
|||
|
||||
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates>(min)() { return (boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::min)(); }
|
||||
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates>(max)() { return (boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::max)(); }
|
||||
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> lowest() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::zero(); }
|
||||
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> lowest() { return -(max)(); }
|
||||
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> epsilon() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::eps(); }
|
||||
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> round_error() { return 0.5L; }
|
||||
static constexpr boost::multiprecision::number<boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>, ExpressionTemplates> infinity() { return boost::multiprecision::cpp_dec_float<Digits10, ExponentType, Allocator>::inf(); }
|
||||
|
|
|
|||
169
include/boost/multiprecision/cpp_df_qf/cpp_df_qf_detail.hpp
Normal file
169
include/boost/multiprecision/cpp_df_qf/cpp_df_qf_detail.hpp
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright 2021 Fahad Syed.
|
||||
// Copyright 2021 - 2025 Christopher Kormanyos.
|
||||
// Copyright 2021 Janek Kozicki.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_2023_01_02_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_2023_01_02_HPP
|
||||
|
||||
#include <boost/multiprecision/detail/standalone_config.hpp>
|
||||
|
||||
#if defined(BOOST_HAS_FLOAT128)
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<quadmath.h>)
|
||||
|
||||
#include <quadmath.h>
|
||||
|
||||
#if !defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128)
|
||||
#define BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128
|
||||
#endif
|
||||
|
||||
#endif // __has_include(<quadmath.h>)
|
||||
#endif // defined(__has_include)
|
||||
#endif // defined(BOOST_HAS_FLOAT128)
|
||||
|
||||
#include <boost/multiprecision/number.hpp>
|
||||
#include <boost/multiprecision/detail/float128_functions.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath.hpp>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail {
|
||||
|
||||
template <class FloatingPointTypeA, class FloatingPointTypeB>
|
||||
struct pair
|
||||
{
|
||||
static_assert(std::is_same<FloatingPointTypeA, FloatingPointTypeB>::value, "Error: floating point types A and B must be identical");
|
||||
|
||||
using float_type = FloatingPointTypeA;
|
||||
|
||||
float_type first;
|
||||
float_type second;
|
||||
|
||||
constexpr pair() : first { }, second { } { };
|
||||
constexpr pair(float_type a, float_type b) : first { a }, second { b } { }
|
||||
constexpr pair(const pair& other) : first { other.first }, second { other.second } { }
|
||||
constexpr pair(pair&& other) noexcept : first { other.first }, second { other.second } { }
|
||||
|
||||
constexpr auto operator=(const pair& other) -> pair&
|
||||
{
|
||||
if (this != &other)
|
||||
{
|
||||
first = other.first;
|
||||
second = other.second;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr auto operator=(pair&& other) noexcept -> pair&
|
||||
{
|
||||
first = other.first;
|
||||
second = other.second;
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class FloatingPointType>
|
||||
struct is_floating_point
|
||||
{
|
||||
static constexpr auto value = ::std::is_same<FloatingPointType, float>::value
|
||||
|| ::std::is_same<FloatingPointType, double>::value
|
||||
|| ::std::is_same<FloatingPointType, long double>::value
|
||||
#if defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128)
|
||||
|| ::std::is_same<FloatingPointType, ::boost::float128_type>::value
|
||||
#endif
|
||||
;
|
||||
};
|
||||
|
||||
template <typename FloatType>
|
||||
struct split_maker
|
||||
{
|
||||
private:
|
||||
using float_type = FloatType;
|
||||
|
||||
public:
|
||||
static constexpr int
|
||||
n_shl
|
||||
{
|
||||
static_cast<int>((ccmath::numeric_limits<float_type>::digits + 1) / 2)
|
||||
};
|
||||
|
||||
static_assert(n_shl < std::numeric_limits<std::uint64_t>::digits,
|
||||
"Error: Left-shift amount for split does not fin in std::uint64_t");
|
||||
|
||||
static constexpr float_type
|
||||
value
|
||||
{
|
||||
static_cast<float_type>
|
||||
(
|
||||
std::uint64_t
|
||||
{
|
||||
UINT64_C(1)
|
||||
+ std::uint64_t { UINT64_C(1) << static_cast<unsigned>(n_shl) }
|
||||
}
|
||||
)
|
||||
};
|
||||
};
|
||||
|
||||
template <typename FloatingPointType>
|
||||
struct exact_arithmetic
|
||||
{
|
||||
// The exact_arithmetic<> struct implements a few extended
|
||||
// precision algorithms that are used in cpp_double_fp_backend.
|
||||
|
||||
static_assert(is_floating_point<FloatingPointType>::value, "Error: exact_arithmetic<> invoked with unknown floating-point type");
|
||||
|
||||
using float_type = FloatingPointType;
|
||||
using float_pair = pair<float_type, float_type>;
|
||||
|
||||
static constexpr auto two_sum(const float_type a, const float_type b) -> float_pair
|
||||
{
|
||||
const float_type hi { a + b };
|
||||
const float_type a1 { hi - b };
|
||||
|
||||
return { hi, float_type { (a - a1) + (b - float_type { hi - a1 }) } };
|
||||
}
|
||||
|
||||
static constexpr auto two_diff(const float_type a, const float_type b) -> float_pair
|
||||
{
|
||||
const float_type hi { a - b };
|
||||
const float_type a1 { hi + b };
|
||||
|
||||
return { hi, float_type { (a - a1) - (b + float_type { hi - a1 }) } };
|
||||
}
|
||||
|
||||
static constexpr auto two_hilo_sum(const float_type a, const float_type b) -> float_pair
|
||||
{
|
||||
const float_type hi { a + b };
|
||||
|
||||
return { hi, float_type { b - (hi - a) } };
|
||||
}
|
||||
|
||||
static constexpr auto normalize(float_type a, float_type b) -> float_pair
|
||||
{
|
||||
const float_type u { a + b };
|
||||
|
||||
return
|
||||
{
|
||||
u,
|
||||
float_type { a - u } + b
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
template<typename ArithmeticType>
|
||||
struct pow2_maker
|
||||
{
|
||||
static constexpr auto value(const int power_value) noexcept -> ArithmeticType
|
||||
{
|
||||
return ((power_value == 0) ? ArithmeticType { 1 } : ArithmeticType { 2 } * pow2_maker<ArithmeticType>::value(power_value - 1));
|
||||
}
|
||||
};
|
||||
|
||||
} } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_2023_01_02_HPP
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2023 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_2023_01_07_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_2023_01_07_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_fabs.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_floor.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_fma.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_fpclassify.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_frexp.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isinf.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isnan.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_ldexp.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_limits.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_log.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_sqrt.hpp>
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_2023_01_07_HPP
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2023 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_FABS_2023_01_07_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FABS_2023_01_07_HPP
|
||||
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isnan.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_limits.hpp>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
template <class Real>
|
||||
constexpr auto fabs(Real x) -> Real
|
||||
{
|
||||
return (cpp_df_qf_detail::ccmath::isnan(x)) ? cpp_df_qf_detail::ccmath::numeric_limits<Real>::quiet_NaN()
|
||||
: (x == static_cast<Real>(-0)) ? static_cast<Real>(0)
|
||||
: (x >= 0) ? x
|
||||
: -x;
|
||||
};
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FABS_2023_01_07_HPP
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2024 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_FLOOR_2024_12_30_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FLOOR_2024_12_30_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
constexpr auto floor_impl(T x) -> T
|
||||
{
|
||||
// Default to the regular floor function.
|
||||
using std::floor;
|
||||
|
||||
return floor(x);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto floor(Real x) -> Real
|
||||
{
|
||||
return cpp_df_qf_detail::ccmath::detail::floor_impl<Real>(x);
|
||||
}
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FLOOR_2024_12_30_HPP
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2024 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_FMA_2024_12_17_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FMA_2024_12_17_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
namespace unsafe {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
constexpr auto fma_impl(T x, T y, T z) noexcept -> T
|
||||
{
|
||||
// Default to the written-out operations ...
|
||||
// ... and hope the compiler chooses FMA if available).
|
||||
|
||||
return (x * y) + z;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER)
|
||||
template <>
|
||||
constexpr auto fma_impl<float>(float x, float y, float z) noexcept -> float
|
||||
{
|
||||
return __builtin_fmaf(x, y, z);
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr auto fma_impl<double>(double x, double y, double z) noexcept -> double
|
||||
{
|
||||
return __builtin_fma(x, y, z);
|
||||
}
|
||||
|
||||
template <>
|
||||
constexpr auto fma_impl<long double>(long double x, long double y, long double z) noexcept -> long double
|
||||
{
|
||||
return __builtin_fmal(x, y, z);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto fma(Real x, Real y, Real z) noexcept -> Real
|
||||
{
|
||||
return detail::fma_impl(x, y, z);
|
||||
}
|
||||
|
||||
} // namespace unsafe
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FMA_2024_12_17_HPP
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2024 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_FPCLASSIFY_2024_12_26_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FPCLASSIFY_2024_12_26_HPP
|
||||
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_fabs.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isinf.hpp>
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isnan.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
template <typename T>
|
||||
constexpr auto fpclassify(T x) -> int
|
||||
{
|
||||
if ((::boost::multiprecision::backends::cpp_df_qf_detail::ccmath::isnan)(x))
|
||||
{
|
||||
return FP_NAN;
|
||||
}
|
||||
else if ((::boost::multiprecision::backends::cpp_df_qf_detail::ccmath::isinf)(x))
|
||||
{
|
||||
return FP_INFINITE;
|
||||
}
|
||||
else
|
||||
{
|
||||
const T fabs_x { ::boost::multiprecision::backends::cpp_df_qf_detail::ccmath::fabs(x) };
|
||||
|
||||
if (fabs_x == T(0))
|
||||
{
|
||||
return FP_ZERO;
|
||||
}
|
||||
else if ((fabs_x > 0) && (fabs_x < (::boost::multiprecision::backends::cpp_df_qf_detail::ccmath::numeric_limits<T>::min)()))
|
||||
{
|
||||
return FP_SUBNORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FP_NORMAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FPCLASSIFY_2024_12_26_HPP
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2023 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_FREXP_2023_01_07_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FREXP_2023_01_07_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template <class T>
|
||||
constexpr auto frexp_impl(T arg, int* expptr) -> T
|
||||
{
|
||||
// Default to the regular frexp function.
|
||||
using std::frexp;
|
||||
|
||||
return frexp(arg, expptr);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto frexp(Real arg, int* expptr) -> Real
|
||||
{
|
||||
return detail::frexp_impl(arg, expptr);
|
||||
}
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_FREXP_2023_01_07_HPP
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2023 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_ISINF_2023_01_07_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_ISINF_2023_01_07_HPP
|
||||
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_limits.hpp>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
template <typename FloatingPointType>
|
||||
constexpr auto isinf(FloatingPointType x) noexcept -> bool
|
||||
{
|
||||
return ( ( x == cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::infinity())
|
||||
|| (-x == cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::infinity()));
|
||||
}
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_ISINF_2023_01_07_HPP
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2023 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_ISNAN_2023_01_07_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_ISNAN_2023_01_07_HPP
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
template <class FloatingPointType>
|
||||
constexpr auto isnan(FloatingPointType x) -> bool
|
||||
{
|
||||
return (x != x);
|
||||
}
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_ISNAN_2023_01_07_HPP
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2023 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_LDEXP_2023_01_07_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_LDEXP_2023_01_07_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
constexpr auto ldexp_impl(T arg, int expval) -> T
|
||||
{
|
||||
// Default to the regular ldexp function.
|
||||
using std::ldexp;
|
||||
|
||||
return ldexp(arg, expval);
|
||||
}
|
||||
|
||||
} // Namespace detail
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto ldexp(Real arg, int expval) -> Real
|
||||
{
|
||||
return detail::ldexp_impl(arg, expval);
|
||||
}
|
||||
|
||||
namespace unsafe {
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto ldexp(Real arg, int exp) noexcept -> Real
|
||||
{
|
||||
while(exp > 0)
|
||||
{
|
||||
arg *= 2;
|
||||
--exp;
|
||||
}
|
||||
while(exp < 0)
|
||||
{
|
||||
arg /= 2;
|
||||
++exp;
|
||||
}
|
||||
|
||||
return arg;
|
||||
}
|
||||
|
||||
} // namespace unsafe
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_LDEXP_2023_01_07_HPP
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2023 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_LIMITS_2023_01_07_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_LIMITS_2023_01_07_HPP
|
||||
|
||||
#include <cfloat>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
template <class FloatingPointType,
|
||||
class EnableType = void>
|
||||
struct numeric_limits
|
||||
{
|
||||
static constexpr bool is_specialized = false;
|
||||
};
|
||||
|
||||
template <class FloatingPointType>
|
||||
struct numeric_limits<FloatingPointType,
|
||||
typename std::enable_if<( std::is_same<FloatingPointType, float>::value
|
||||
|| std::is_same<FloatingPointType, double>::value
|
||||
|| std::is_same<FloatingPointType, long double>::value)>::type>
|
||||
{
|
||||
private:
|
||||
using float_type = FloatingPointType;
|
||||
|
||||
public:
|
||||
static constexpr bool is_specialized = std::numeric_limits<float_type>::is_specialized;
|
||||
static constexpr bool is_signed = std::numeric_limits<float_type>::is_signed;
|
||||
static constexpr bool is_integer = std::numeric_limits<float_type>::is_integer;
|
||||
static constexpr bool is_exact = std::numeric_limits<float_type>::is_exact;
|
||||
static constexpr bool is_bounded = std::numeric_limits<float_type>::is_bounded;
|
||||
static constexpr bool is_modulo = std::numeric_limits<float_type>::is_modulo;
|
||||
static constexpr bool is_iec559 = std::numeric_limits<float_type>::is_iec559;
|
||||
static constexpr std::float_denorm_style has_denorm = std::numeric_limits<float_type>::has_denorm;
|
||||
static constexpr bool has_infinity = std::numeric_limits<float_type>::has_infinity;
|
||||
static constexpr bool has_quiet_NaN = std::numeric_limits<float_type>::has_quiet_NaN;
|
||||
static constexpr bool has_signaling_NaN = std::numeric_limits<float_type>::has_signaling_NaN;
|
||||
static constexpr bool has_denorm_loss = std::numeric_limits<float_type>::has_denorm_loss;
|
||||
static constexpr bool traps = std::numeric_limits<float_type>::traps;
|
||||
static constexpr bool tinyness_before = std::numeric_limits<float_type>::tinyness_before;
|
||||
static constexpr std::float_round_style round_style = std::numeric_limits<float_type>::round_style;
|
||||
|
||||
static constexpr int radix = std::numeric_limits<float_type>::radix;
|
||||
static constexpr int digits = std::numeric_limits<float_type>::digits;
|
||||
static constexpr int digits10 = std::numeric_limits<float_type>::digits10;
|
||||
static constexpr int max_digits10 = std::numeric_limits<float_type>::max_digits10;
|
||||
|
||||
static constexpr int max_exponent = std::numeric_limits<float_type>::max_exponent;
|
||||
static constexpr int min_exponent = std::numeric_limits<float_type>::min_exponent;
|
||||
static constexpr int max_exponent10 = std::numeric_limits<float_type>::max_exponent10;
|
||||
static constexpr int min_exponent10 = std::numeric_limits<float_type>::min_exponent10;
|
||||
|
||||
// LCOV_EXCL_START
|
||||
static constexpr auto (min) () noexcept -> float_type { return (std::numeric_limits<float_type>::min) (); }
|
||||
static constexpr auto (max) () noexcept -> float_type { return (std::numeric_limits<float_type>::max) (); }
|
||||
static constexpr auto lowest () noexcept -> float_type { return std::numeric_limits<float_type>::lowest (); }
|
||||
static constexpr auto epsilon () noexcept -> float_type { return std::numeric_limits<float_type>::epsilon (); }
|
||||
static constexpr auto round_error () noexcept -> float_type { return std::numeric_limits<float_type>::round_error (); }
|
||||
static constexpr auto denorm_min () noexcept -> float_type { return std::numeric_limits<float_type>::denorm_min (); }
|
||||
static constexpr auto infinity () noexcept -> float_type { return std::numeric_limits<float_type>::infinity (); }
|
||||
static constexpr auto quiet_NaN () noexcept -> float_type { return std::numeric_limits<float_type>::quiet_NaN (); }
|
||||
static constexpr auto signaling_NaN() noexcept -> float_type { return std::numeric_limits<float_type>::signaling_NaN(); }
|
||||
// LCOV_EXCL_STOP
|
||||
};
|
||||
|
||||
#if defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128)
|
||||
template <class FloatingPointType>
|
||||
struct numeric_limits<FloatingPointType,
|
||||
typename std::enable_if<std::is_same<FloatingPointType, ::boost::float128_type>::value>::type>
|
||||
{
|
||||
private:
|
||||
using self_type = ::boost::float128_type;
|
||||
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool is_integer = false;
|
||||
static constexpr bool is_exact = false;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = false;
|
||||
static constexpr bool is_iec559 = true;
|
||||
static constexpr std::float_denorm_style has_denorm = std::denorm_present;
|
||||
static constexpr bool has_infinity = true;
|
||||
static constexpr bool has_quiet_NaN = true;
|
||||
static constexpr bool has_signaling_NaN = false;
|
||||
static constexpr bool has_denorm_loss = true;
|
||||
static constexpr bool traps = false;
|
||||
static constexpr bool tinyness_before = false;
|
||||
static constexpr std::float_round_style round_style = std::round_to_nearest;
|
||||
|
||||
static constexpr int radix = 2;
|
||||
static constexpr int digits = 113;
|
||||
static constexpr int digits10 = 33;
|
||||
static constexpr int max_digits10 = 36;
|
||||
|
||||
static constexpr int max_exponent = 16384;
|
||||
static constexpr int min_exponent = -16381;
|
||||
static constexpr int max_exponent10 = static_cast<int>(static_cast<long long>(static_cast<long long>(max_exponent) * 301LL) / 1000LL);
|
||||
static constexpr int min_exponent10 = static_cast<int>(static_cast<long long>(static_cast<long long>(min_exponent) * 301LL) / 1000LL);
|
||||
|
||||
static constexpr auto (min)() noexcept -> self_type
|
||||
{
|
||||
return static_cast<self_type>(1)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN) / 1073741824;
|
||||
}
|
||||
|
||||
static constexpr auto (max)() noexcept -> self_type
|
||||
{
|
||||
// This has one bit set only.
|
||||
constexpr double dbl_mult = 8.9884656743115795386e+307;
|
||||
|
||||
return (static_cast<self_type>(1) - 9.62964972193617926527988971292463659e-35) // This now has all bits sets to 1
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult)
|
||||
* static_cast<self_type>(dbl_mult) * 65536;
|
||||
}
|
||||
|
||||
static constexpr auto lowest() noexcept -> self_type { return -(max)(); }
|
||||
|
||||
static constexpr auto epsilon() -> self_type
|
||||
{
|
||||
// This double value has only one bit set and so is exact.
|
||||
return 1.92592994438723585305597794258492732e-34;
|
||||
}
|
||||
|
||||
static constexpr auto round_error() noexcept -> self_type { return static_cast<self_type>(0.5F); }
|
||||
|
||||
static constexpr auto denorm_min() noexcept -> self_type
|
||||
{
|
||||
return static_cast<self_type>(1)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
* static_cast<self_type>(DBL_MIN)
|
||||
/ 5.5751862996326557854e+42;
|
||||
}
|
||||
|
||||
static constexpr auto infinity () noexcept -> self_type { return HUGE_VAL; }
|
||||
static constexpr auto quiet_NaN () noexcept -> self_type { return NAN; }
|
||||
static constexpr auto signaling_NaN() noexcept -> self_type { return 0; }
|
||||
};
|
||||
#endif
|
||||
|
||||
} } } } } // namespace boost::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_LIMITS_2023_01_07_HPP
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2024 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_LOG_2024_12_30_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_LOG_2024_12_30_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
constexpr auto log_impl(T x) -> T
|
||||
{
|
||||
// Default to the regular log function.
|
||||
using std::log;
|
||||
|
||||
return log(x);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto log(Real x) -> Real
|
||||
{
|
||||
return cpp_df_qf_detail::ccmath::detail::log_impl<Real>(x);
|
||||
}
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_LOG_2024_12_30_HPP
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2023 - 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CCMATH_SQRT_2023_01_07_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_SQRT_2023_01_07_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <type_traits>
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <class T>
|
||||
constexpr auto sqrt_impl(T x) -> T
|
||||
{
|
||||
// Default to the regular sqrt function.
|
||||
using std::sqrt;
|
||||
|
||||
return sqrt(x);
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto sqrt(Real x) -> Real
|
||||
{
|
||||
return cpp_df_qf_detail::ccmath::detail::sqrt_impl<Real>(x);
|
||||
}
|
||||
|
||||
namespace unsafe {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto sqrt_impl_2(Real x, Real s, Real s2) noexcept -> Real
|
||||
{
|
||||
return !(s < s2) ? s2 : sqrt_impl_2(x, (x / s + s) / 2, s);
|
||||
}
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto sqrt_impl_1(Real x, Real s) noexcept -> Real
|
||||
{
|
||||
return sqrt_impl_2(x, (x / s + s) / 2, s);
|
||||
}
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto sqrt_impl(Real x) noexcept -> Real
|
||||
{
|
||||
return sqrt_impl_1(x, x > 1 ? x : Real(1));
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <typename Real>
|
||||
constexpr auto sqrt(Real x) noexcept -> Real
|
||||
{
|
||||
return detail::sqrt_impl<Real>(x);
|
||||
}
|
||||
|
||||
} // namespace unsafe
|
||||
|
||||
} } } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail::ccmath
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CCMATH_SQRT_2023_01_07_HPP
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright Christopher Kormanyos 2025.
|
||||
// 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_MP_CPP_DF_QF_DETAIL_CONSTANTS_2025_06_23_HPP
|
||||
#define BOOST_MP_CPP_DF_QF_DETAIL_CONSTANTS_2025_06_23_HPP
|
||||
|
||||
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#if (defined(__GNUC__) && defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128))
|
||||
//
|
||||
// This is the only way we can avoid
|
||||
// warning: non-standard suffix on floating constant [-Wpedantic]
|
||||
// when building with -Wall -pedantic. Neither __extension__
|
||||
// nor #pragma diagnostic ignored work :(
|
||||
//
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail {
|
||||
|
||||
// N[Pi, 101]
|
||||
// 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170680
|
||||
|
||||
// 3.14159250259, 1.50995788317e-07
|
||||
// 3.141592653589793116, 1.2246467991473529607e-16
|
||||
// 3.14159265358979323851281, -5.01655761266833202345176e-20
|
||||
// 3.14159265358979323846264338327950279748, 8.67181013012378102479704402604335225411e-35
|
||||
|
||||
template <typename FloatingPointType> constexpr auto constant_df_pi() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 24)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(3.14159250259L), static_cast<FloatingPointType>(1.50995788317e-07L) }; }
|
||||
template <typename FloatingPointType> constexpr auto constant_df_pi() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 53)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(3.141592653589793116L), static_cast<FloatingPointType>(1.2246467991473529607e-16L) }; }
|
||||
template <typename FloatingPointType> constexpr auto constant_df_pi() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 64)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(3.14159265358979323851281L), static_cast<FloatingPointType>(-5.01655761266833202345176e-20L) }; }
|
||||
#if defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128)
|
||||
template <typename FloatingPointType> constexpr auto constant_df_pi() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 113)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(3.14159265358979323846264338327950279748Q), static_cast<FloatingPointType>(8.67181013012378102479704402604335225411e-35Q) }; }
|
||||
#else
|
||||
template <typename FloatingPointType> constexpr auto constant_df_pi() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 113)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(3.14159265358979323846264338327950279748L), static_cast<FloatingPointType>(8.67181013012378102479704402604335225411e-35L) }; }
|
||||
#endif
|
||||
|
||||
// N[Log[2], 101]
|
||||
// 0.69314718055994530941723212145817656807550013436025525412068000949339362196969471560586332699641868754
|
||||
|
||||
// 0.69314712286, 5.76999887869e-08
|
||||
// 0.6931471805599451752, 1.3421277060097865271e-16
|
||||
// 0.69314718055994530942869, -1.14583527267987328094768e-20
|
||||
// 0.693147180559945309417232121458176575084, -7.00813947454958516341266200877162272784e-36
|
||||
|
||||
template <typename FloatingPointType> constexpr auto constant_df_ln_two() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 24)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(0.69314712286L), static_cast<FloatingPointType>(5.76999887869e-08L) }; }
|
||||
template <typename FloatingPointType> constexpr auto constant_df_ln_two() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 53)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(0.6931471805599451752L), static_cast<FloatingPointType>(1.3421277060097865271e-16L) }; }
|
||||
template <typename FloatingPointType> constexpr auto constant_df_ln_two() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 64)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(0.69314718055994530942869L), static_cast<FloatingPointType>(-1.14583527267987328094768e-20L) }; }
|
||||
#if defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128)
|
||||
template <typename FloatingPointType> constexpr auto constant_df_ln_two() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 113)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(0.693147180559945309417232121458176575084Q), static_cast<FloatingPointType>(-7.00813947454958516341266200877162272784e-36Q) }; }
|
||||
#else
|
||||
template <typename FloatingPointType> constexpr auto constant_df_ln_two() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 113)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(0.693147180559945309417232121458176575084L), static_cast<FloatingPointType>(-7.00813947454958516341266200877162272784e-36L) }; }
|
||||
#endif
|
||||
|
||||
// N[Exp[1], 101]
|
||||
// 2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274
|
||||
|
||||
// 2.71828174591, 8.25483965627e-08
|
||||
// 2.7182818284590450908, 1.4456468917292501578e-16
|
||||
// 2.71828182845904523521133, 1.4895979785582304563159e-19
|
||||
// 2.71828182845904523536028747135266231436, 1.83398825226506410712297736767396397644e-34
|
||||
|
||||
template <typename FloatingPointType> constexpr auto constant_df_exp1() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 24)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(2.71828174591L), static_cast<FloatingPointType>(8.25483965627e-08L) }; }
|
||||
template <typename FloatingPointType> constexpr auto constant_df_exp1() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 53)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(2.7182818284590450908L), static_cast<FloatingPointType>(1.4456468917292501578e-16L) }; }
|
||||
template <typename FloatingPointType> constexpr auto constant_df_exp1() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 64)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(2.71828182845904523521133L), static_cast<FloatingPointType>(1.4895979785582304563159e-19L) }; }
|
||||
#if defined(BOOST_MP_CPP_DOUBLE_FP_HAS_FLOAT128)
|
||||
template <typename FloatingPointType> constexpr auto constant_df_exp1() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 113)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(2.71828182845904523536028747135266231436Q), static_cast<FloatingPointType>(1.83398825226506410712297736767396397644e-34Q) }; }
|
||||
#else
|
||||
template <typename FloatingPointType> constexpr auto constant_df_exp1() -> typename ::std::enable_if<(cpp_df_qf_detail::is_floating_point<FloatingPointType>::value && (cpp_df_qf_detail::ccmath::numeric_limits<FloatingPointType>::digits == 113)), cpp_double_fp_backend<FloatingPointType>>::type { return { static_cast<FloatingPointType>(2.71828182845904523536028747135266231436L), static_cast<FloatingPointType>(1.83398825226506410712297736767396397644e-34L) }; }
|
||||
#endif
|
||||
|
||||
} } } } // namespace boost::multiprecision::backends::cpp_df_qf_detail
|
||||
|
||||
#endif // BOOST_MP_CPP_DF_QF_DETAIL_CONSTANTS_2025_06_23_HPP
|
||||
2634
include/boost/multiprecision/cpp_double_fp.hpp
Normal file
2634
include/boost/multiprecision/cpp_double_fp.hpp
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -563,7 +563,11 @@ inline BOOST_MP_CXX14_CONSTEXPR void right_shift_limb(Int& result, double_limb_t
|
|||
pr[i] = pr[i + offset];
|
||||
result.resize(rs, rs);
|
||||
}
|
||||
|
||||
// see discussion at https://github.com/boostorg/multiprecision/issues/686 for logic in disabling this.
|
||||
#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
template <class Int>
|
||||
inline BOOST_MP_CXX14_CONSTEXPR void right_shift_generic(Int& result, double_limb_type s)
|
||||
{
|
||||
|
|
@ -598,6 +602,9 @@ inline BOOST_MP_CXX14_CONSTEXPR void right_shift_generic(Int& result, double_lim
|
|||
pr[i] = pr[i + offset] >> shift;
|
||||
result.resize(rs, rs);
|
||||
}
|
||||
#if defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 12)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
template <std::size_t MinBits1, std::size_t MaxBits1, cpp_int_check_type Checked1, class Allocator1>
|
||||
inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<!is_trivial_cpp_int<cpp_int_backend<MinBits1, MaxBits1, unsigned_magnitude, Checked1, Allocator1> >::value>::type
|
||||
|
|
@ -700,7 +707,7 @@ BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<is_trivial
|
|||
eval_left_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>& result, T s) noexcept((is_non_throwing_cpp_int<cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1> >::value))
|
||||
{
|
||||
is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
|
||||
*result.limbs() = detail::checked_left_shift(*result.limbs(), s, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
|
||||
*result.limbs() = detail::checked_left_shift(*result.limbs(), static_cast<unsigned long long>(s), typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
|
||||
result.normalize();
|
||||
}
|
||||
|
||||
|
|
@ -710,7 +717,7 @@ eval_right_shift(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Alloca
|
|||
{
|
||||
// Nothing to check here... just make sure we don't invoke undefined behavior:
|
||||
is_valid_bitwise_op(result, typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::checked_type());
|
||||
*result.limbs() = (static_cast<unsigned>(s) >= sizeof(*result.limbs()) * CHAR_BIT) ? 0 : (result.sign() ? ((--*result.limbs()) >> s) + 1 : *result.limbs() >> s);
|
||||
*result.limbs() = (static_cast<std::size_t>(s) >= static_cast<std::size_t>(sizeof(*result.limbs()) * CHAR_BIT)) ? 0 : (result.sign() ? ((--*result.limbs()) >> s) + 1 : *result.limbs() >> s);
|
||||
if (result.sign() && (*result.limbs() == 0))
|
||||
result = static_cast<signed_limb_type>(-1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,29 +249,30 @@ constexpr typename boost::multiprecision::literals::detail::unsigned_cpp_int_lit
|
|||
return boost::multiprecision::literals::detail::make_backend_from_pack<pt, typename boost::multiprecision::literals::detail::unsigned_cpp_int_literal_result_type<static_cast<unsigned>((sizeof...(STR)) - 2u)>::backend_type>::value;
|
||||
}
|
||||
|
||||
#define BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(Bits) \
|
||||
template <char... STR> \
|
||||
constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > operator BOOST_JOIN(""_cppi, Bits)() \
|
||||
{ \
|
||||
using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type; \
|
||||
return boost::multiprecision::literals::detail::make_backend_from_pack< \
|
||||
pt, \
|
||||
boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >::value; \
|
||||
} \
|
||||
template <char... STR> \
|
||||
constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> > operator BOOST_JOIN(""_cppui, Bits)() \
|
||||
{ \
|
||||
using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type; \
|
||||
return boost::multiprecision::literals::detail::make_backend_from_pack< \
|
||||
pt, \
|
||||
boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> >::value; \
|
||||
#define BOOST_MP_LIT(P, N) BOOST_JOIN(operator "", BOOST_JOIN(P, N))
|
||||
#define BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(Bits) \
|
||||
template <char... STR> \
|
||||
constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> > BOOST_MP_LIT(_cppi, Bits)() \
|
||||
{ \
|
||||
using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type; \
|
||||
return boost::multiprecision::literals::detail::make_backend_from_pack< \
|
||||
pt, \
|
||||
boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void> >::value; \
|
||||
} \
|
||||
template <char... STR> \
|
||||
constexpr boost::multiprecision::number<boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> > BOOST_MP_LIT(_cppui, Bits)() \
|
||||
{ \
|
||||
using pt = typename boost::multiprecision::literals::detail::make_packed_value_from_str<STR...>::type; \
|
||||
return boost::multiprecision::literals::detail::make_backend_from_pack< \
|
||||
pt, \
|
||||
boost::multiprecision::backends::cpp_int_backend<Bits, Bits, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void> >::value; \
|
||||
}
|
||||
|
||||
BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(128)
|
||||
BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(256)
|
||||
BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(512)
|
||||
BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(1024)
|
||||
|
||||
#undef BOOST_MP_LIT
|
||||
} // namespace literals
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -11,19 +11,15 @@
|
|||
#ifndef BOOST_MP_CPP_INT_MISC_HPP
|
||||
#define BOOST_MP_CPP_INT_MISC_HPP
|
||||
|
||||
#include <boost/multiprecision/detail/standalone_config.hpp>
|
||||
#include <boost/multiprecision/detail/number_base.hpp>
|
||||
#include <boost/multiprecision/cpp_int/cpp_int_config.hpp>
|
||||
#include <boost/multiprecision/detail/float128_functions.hpp>
|
||||
#include <boost/multiprecision/detail/assert.hpp>
|
||||
#include <boost/multiprecision/detail/constexpr.hpp>
|
||||
#include <boost/multiprecision/detail/bitscan.hpp> // lsb etc
|
||||
#include <boost/multiprecision/detail/constexpr.hpp>
|
||||
#include <boost/multiprecision/detail/float128_functions.hpp>
|
||||
#include <boost/multiprecision/detail/hash.hpp>
|
||||
#include <boost/multiprecision/detail/no_exceptions_support.hpp>
|
||||
#include <numeric> // std::gcd
|
||||
#include <type_traits>
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
#include <boost/multiprecision/detail/number_base.hpp>
|
||||
#include <boost/multiprecision/detail/standalone_config.hpp>
|
||||
|
||||
#ifndef BOOST_MP_STANDALONE
|
||||
#include <boost/integer/common_factor_rt.hpp>
|
||||
|
|
@ -33,6 +29,15 @@
|
|||
#include <boost/math/special_functions/next.hpp>
|
||||
#endif
|
||||
|
||||
#if ((defined(__cpp_lib_gcd_lcm) && (__cpp_lib_gcd_lcm >= 201606L)) && (!defined(BOOST_HAS_INT128) || !defined(__STRICT_ANSI__)))
|
||||
#define BOOST_MP_LIB_GCD_LCM_AVAILABLE
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
#include <numeric>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4702)
|
||||
|
|
@ -517,7 +522,7 @@ BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_type eval_gcd(limb_type u, li
|
|||
// boundary cases
|
||||
if (!u || !v)
|
||||
return u | v;
|
||||
#if (defined(__cpp_lib_gcd_lcm) && (__cpp_lib_gcd_lcm >= 201606L))
|
||||
#if defined(BOOST_MP_LIB_GCD_LCM_AVAILABLE)
|
||||
return std::gcd(u, v);
|
||||
#else
|
||||
std::size_t shift = boost::multiprecision::detail::find_lsb(u | v);
|
||||
|
|
@ -535,7 +540,7 @@ BOOST_MP_FORCEINLINE BOOST_MP_CXX14_CONSTEXPR limb_type eval_gcd(limb_type u, li
|
|||
|
||||
inline BOOST_MP_CXX14_CONSTEXPR double_limb_type eval_gcd(double_limb_type u, double_limb_type v)
|
||||
{
|
||||
#if (defined(__cpp_lib_gcd_lcm) && (__cpp_lib_gcd_lcm >= 201606L)) && (!defined(BOOST_HAS_INT128) || !defined(__STRICT_ANSI__))
|
||||
#if defined(BOOST_MP_LIB_GCD_LCM_AVAILABLE)
|
||||
return std::gcd(u, v);
|
||||
#else
|
||||
if (u == 0)
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ class binary_iarchive;
|
|||
|
||||
namespace serialization {
|
||||
|
||||
namespace mp = boost::multiprecision;
|
||||
|
||||
namespace cpp_int_detail {
|
||||
|
||||
using namespace boost::multiprecision;
|
||||
|
|
@ -191,12 +189,12 @@ void do_serialize(Archive& ar, Int& val, std::integral_constant<bool, true> cons
|
|||
|
||||
} // namespace cpp_int_detail
|
||||
|
||||
template <class Archive, std::size_t MinBits, std::size_t MaxBits, mp::cpp_integer_type SignType, mp::cpp_int_check_type Checked, class Allocator>
|
||||
void serialize(Archive& ar, mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& val, const unsigned int /*version*/)
|
||||
template <class Archive, std::size_t MinBits, std::size_t MaxBits, multiprecision::cpp_integer_type SignType, multiprecision::cpp_int_check_type Checked, class Allocator>
|
||||
void serialize(Archive& ar, multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator>& val, const unsigned int /*version*/)
|
||||
{
|
||||
using archive_save_tag = typename Archive::is_saving ;
|
||||
using save_tag = std::integral_constant<bool, archive_save_tag::value> ;
|
||||
using trivial_tag = std::integral_constant<bool, mp::backends::is_trivial_cpp_int<mp::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value>;
|
||||
using trivial_tag = std::integral_constant<bool, multiprecision::backends::is_trivial_cpp_int<multiprecision::cpp_int_backend<MinBits, MaxBits, SignType, Checked, Allocator> >::value>;
|
||||
using binary_tag = typename cpp_int_detail::is_binary_archive<Archive>::type ;
|
||||
|
||||
// Just dispatch to the correct method:
|
||||
|
|
|
|||
|
|
@ -2843,7 +2843,7 @@ template <class tag, class A1, class A2, class A3, class A4, class Policy>
|
|||
inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<tag, A1, A2, A3, A4>::result_type trunc(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
|
||||
{
|
||||
using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type;
|
||||
return std::move(trunc(number_type(v), pol));
|
||||
return trunc(number_type(v), pol);
|
||||
}
|
||||
|
||||
template <class Backend, expression_template_option ExpressionTemplates, class Policy>
|
||||
|
|
@ -2943,7 +2943,7 @@ template <class tag, class A1, class A2, class A3, class A4, class Policy>
|
|||
inline BOOST_MP_CXX14_CONSTEXPR typename detail::expression<tag, A1, A2, A3, A4>::result_type round(const detail::expression<tag, A1, A2, A3, A4>& v, const Policy& pol)
|
||||
{
|
||||
using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type;
|
||||
return std::move(round(static_cast<number_type>(v), pol));
|
||||
return round(static_cast<number_type>(v), pol);
|
||||
}
|
||||
template <class T, expression_template_option ExpressionTemplates, class Policy>
|
||||
inline BOOST_MP_CXX14_CONSTEXPR number<T, ExpressionTemplates> round(const number<T, ExpressionTemplates>& v, const Policy&)
|
||||
|
|
@ -3057,7 +3057,7 @@ inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename
|
|||
frexp(const detail::expression<tag, A1, A2, A3, A4>& v, short* pint)
|
||||
{
|
||||
using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type;
|
||||
return std::move(frexp(static_cast<number_type>(v), pint));
|
||||
return frexp(static_cast<number_type>(v), pint);
|
||||
}
|
||||
template <class T, expression_template_option ExpressionTemplates>
|
||||
inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, int* pint)
|
||||
|
|
@ -3073,7 +3073,7 @@ inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename
|
|||
frexp(const detail::expression<tag, A1, A2, A3, A4>& v, int* pint)
|
||||
{
|
||||
using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type;
|
||||
return std::move(frexp(static_cast<number_type>(v), pint));
|
||||
return frexp(static_cast<number_type>(v), pint);
|
||||
}
|
||||
template <class T, expression_template_option ExpressionTemplates>
|
||||
inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, long* pint)
|
||||
|
|
@ -3089,7 +3089,7 @@ inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename
|
|||
frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long* pint)
|
||||
{
|
||||
using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type;
|
||||
return std::move(frexp(static_cast<number_type>(v), pint));
|
||||
return frexp(static_cast<number_type>(v), pint);
|
||||
}
|
||||
template <class T, expression_template_option ExpressionTemplates>
|
||||
inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<T>::value == number_kind_floating_point, number<T, ExpressionTemplates> >::type frexp(const number<T, ExpressionTemplates>& v, long long* pint)
|
||||
|
|
@ -3105,7 +3105,7 @@ inline BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<number_category<typename
|
|||
frexp(const detail::expression<tag, A1, A2, A3, A4>& v, long long* pint)
|
||||
{
|
||||
using number_type = typename detail::expression<tag, A1, A2, A3, A4>::result_type;
|
||||
return std::move(frexp(static_cast<number_type>(v), pint));
|
||||
return frexp(static_cast<number_type>(v), pint);
|
||||
}
|
||||
//
|
||||
// modf does not return an expression template since we require the
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ std::string convert_to_string(Backend b, std::streamsize digits, std::ios_base::
|
|||
//
|
||||
// Extract the digits one at a time:
|
||||
//
|
||||
for (unsigned i = 0; i < digits; ++i)
|
||||
for (std::streamsize i = 0; i < digits; ++i)
|
||||
{
|
||||
eval_floor(digit, t);
|
||||
eval_convert_to(&cdigit, digit);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
// Copyright Christopher Kormanyos 2002 - 2013.
|
||||
// Copyright 2011 - 2013 John Maddock.
|
||||
// Copyright 2011 - 2025 John Maddock.
|
||||
// Copyright Christopher Kormanyos 2002 - 2025.
|
||||
// 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)
|
||||
|
|
@ -132,7 +132,6 @@ void hyp0F0(T& H0F0, const T& x)
|
|||
|
||||
BOOST_MP_ASSERT(&H0F0 != &x);
|
||||
long tol = boost::multiprecision::detail::digits2<number<T, et_on> >::value();
|
||||
T t;
|
||||
|
||||
T x_pow_n_div_n_fact(x);
|
||||
|
||||
|
|
@ -192,7 +191,7 @@ void hyp1F0(T& H1F0, const T& a, const T& x)
|
|||
lim.negate();
|
||||
|
||||
si_type n;
|
||||
T term, part;
|
||||
T term;
|
||||
|
||||
const si_type series_limit =
|
||||
boost::multiprecision::detail::digits2<number<T, et_on> >::value() < 100
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ inline constexpr unsigned current_precision_of(const expression<tag, Arg1, Arg2,
|
|||
#endif
|
||||
|
||||
template <class R, bool = boost::multiprecision::detail::is_variable_precision<R>::value>
|
||||
struct scoped_default_precision
|
||||
struct BOOST_ATTRIBUTE_UNUSED scoped_default_precision
|
||||
{
|
||||
template <class T>
|
||||
constexpr scoped_default_precision(const T&) {}
|
||||
|
|
|
|||
|
|
@ -144,9 +144,13 @@ namespace boost { namespace multiprecision {
|
|||
#define BOOST_MP_NO_CONSTEXPR_DETECTION
|
||||
#endif
|
||||
|
||||
#ifdef __has_attribute
|
||||
# if __has_attribute(fallthrough)
|
||||
# define BOOST_MP_FALLTHROUGH [[fallthrough]]
|
||||
// Compilers should ignore unknown attributes,
|
||||
// but this doesn't stop them from issuing warnings
|
||||
#if (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || (defined(__cplusplus) && __cplusplus >= 201703L)
|
||||
# ifdef __has_attribute
|
||||
# if __has_attribute(fallthrough)
|
||||
# define BOOST_MP_FALLTHROUGH [[fallthrough]]
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ struct float128_backend
|
|||
int v_max = v;
|
||||
std::unique_ptr<char[]> buf2;
|
||||
buf2.reset(new char[v + 3]);
|
||||
v = quadmath_snprintf(&buf2[0], v_max + 3, format.c_str(), digits, m_value);
|
||||
v = quadmath_snprintf(&buf2[0], static_cast<std::size_t>(v_max + 3), format.c_str(), digits, m_value);
|
||||
if (v >= v_max + 3)
|
||||
{
|
||||
BOOST_MP_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed."));
|
||||
|
|
|
|||
|
|
@ -2967,6 +2967,8 @@ inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<D
|
|||
boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
|
||||
|
||||
boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
|
||||
if (arg < -1)
|
||||
return policies::raise_domain_error("log1p<%1%>(%1%)", "Argument was %1% but must be greater than -1", arg, pol);
|
||||
mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
|
||||
if (mpfr_inf_p(result.backend().data()))
|
||||
return (arg == -1 ? -1 : 1) * policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("log1p<%1%>(%1%)", nullptr, pol);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
// BOOST_VERSION / 100 % 1000 is the minor version
|
||||
// BOOST_VERSION / 100000 is the major version
|
||||
|
||||
#define BOOST_VERSION 108800
|
||||
#define BOOST_VERSION 108900
|
||||
|
||||
//
|
||||
// BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION
|
||||
|
|
@ -27,6 +27,6 @@
|
|||
// number, y is the minor version number, and z is the patch level if not 0.
|
||||
// This is used by <config/auto_link.hpp> to select which library version to link to.
|
||||
|
||||
#define BOOST_LIB_VERSION "1_88"
|
||||
#define BOOST_LIB_VERSION "1_89"
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue