Updated boost multiprecision, and disabled deprecated declarations warning

This commit is contained in:
Yousef Khadadeh 2025-10-03 13:44:19 +03:00
parent 9f739ada6a
commit 6bc7069099
31 changed files with 3656 additions and 83 deletions

View file

@ -320,6 +320,13 @@ endif()
target_compile_definitions(infinipaint PRIVATE BOOST_MP_STANDALONE EIGEN_MPL2_ONLY)
include(CheckCCompilerFlag)
check_c_compiler_flag(-Wdeprecated-declarations HAS_DEPRECATED_DECLARATIONS)
if(HAS_DEPRECATED_DECLARATIONS)
target_compile_options(infinipaint PRIVATE -Wno-deprecated-declarations)
endif()
if(APPLE OR WIN32)
install(TARGETS infinipaint DESTINATION .)

View file

@ -177,4 +177,9 @@
#endif
#endif
#if _LIBCPP_VERSION <= 170006
// no std::ranges::join_view
# define BOOST_NO_CXX20_HDR_RANGES
#endif
// --- end ---

View file

@ -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>

View file

@ -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(); }

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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);
}

View file

@ -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
//

View file

@ -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)

View file

@ -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:

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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&) {}

View file

@ -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

View file

@ -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."));

View file

@ -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);

View file

@ -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