Skip to content

Commit

Permalink
Simplify float128 support
Browse files Browse the repository at this point in the history
  • Loading branch information
ckormanyos committed Dec 31, 2024
1 parent 1891aaf commit b9ff1a2
Show file tree
Hide file tree
Showing 12 changed files with 120 additions and 127 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2023.
// Copyright Christopher Kormanyos 2023 - 2024.
// 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace detail {
template <class T>
auto floor_impl(T x) -> T
{
// Default to the regular std::floor function.
// Default to the regular floor function.
using std::floor;

return floor(x);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,41 +17,33 @@ namespace unsafe {

namespace detail {

#if defined(BOOST_HAS_FLOAT128)
template <class T>
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_same<T, ::boost::float128_type>::value, T>::type
auto fma_impl(T x, T y, T z) noexcept -> T
{
return ::fmaq(x, y, z);
// Default to the regular fma function.
using std::fma;

return fma(x, y, z);
}
#endif

#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__INTEL_LLVM_COMPILER)
template <class T>
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_same<T, float>::value, T>::type
template <>
auto fma_impl<float>(float x, float y, float z) noexcept -> float
{
return __builtin_fmaf(x, y, z);
}

template <class T>
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_same<T, double>::value, T>::type
template <>
auto fma_impl<double>(double x, double y, double z) noexcept -> double
{
return __builtin_fma(x, y, z);
}

template <class T>
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_same<T, long double>::value, T>::type
template <>
auto fma_impl<long double>(long double x, long double y, long double z) noexcept -> long double
{
return __builtin_fmal(x, y, z);
}
#else
template <class T>
auto fma_impl(T x, T y, T z) noexcept -> typename ::std::enable_if<::std::is_same<T, float>::value || ::std::is_same<T, double>::value || ::std::is_same<T, long double>::value, T>::type
{
// Default to the written-out operations.
using std::fma;

return fma(x, y, z);
}
#endif

} // namespace detail
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include <boost/multiprecision/cpp_df_qf/cpp_df_qf_detail_ccmath_isnan.hpp>

#include <cmath>
#include <type_traits>

namespace boost { namespace multiprecision { namespace backends { namespace cpp_df_qf_detail { namespace ccmath {

Expand All @@ -36,7 +35,7 @@ constexpr auto fpclassify(T x) -> int
{
return FP_ZERO;
}
else if ((fabs_x > 0) && (fabs_x < (boost::multiprecision::backends::cpp_df_qf_detail::ccmath::numeric_limits<T>::min)()))
else if ((fabs_x > 0) && (fabs_x < (::boost::multiprecision::backends::cpp_df_qf_detail::ccmath::numeric_limits<T>::min)()))
{
return FP_SUBNORMAL;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace detail
template <class T>
auto frexp_impl(T arg, int* expptr) -> T
{
// Default to the regular std::frexp function.
// Default to the regular frexp function.
using std::frexp;

return frexp(arg, expptr);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2023.
// Copyright Christopher Kormanyos 2023 - 2024.
// 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)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2023.
// Copyright Christopher Kormanyos 2023 - 2024.
// 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace detail {
template <class T>
auto ldexp_impl(T arg, int expval) -> T
{
// Default to the regular std::ldexp function.
// Default to the regular ldexp function.
using std::ldexp;

return ldexp(arg, expval);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2023.
// Copyright Christopher Kormanyos 2023 - 2024.
// 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)
Expand Down Expand Up @@ -29,44 +29,44 @@ struct numeric_limits<FloatingPointType,
|| std::is_same<FloatingPointType, long double>::value)>::type>
{
private:
using self_type = FloatingPointType;
using float_type = FloatingPointType;

public:
static constexpr bool is_specialized = std::numeric_limits<self_type>::is_specialized;
static constexpr bool is_signed = std::numeric_limits<self_type>::is_signed;
static constexpr bool is_integer = std::numeric_limits<self_type>::is_integer;
static constexpr bool is_exact = std::numeric_limits<self_type>::is_exact;
static constexpr bool is_bounded = std::numeric_limits<self_type>::is_bounded;
static constexpr bool is_modulo = std::numeric_limits<self_type>::is_modulo;
static constexpr bool is_iec559 = std::numeric_limits<self_type>::is_iec559;
static constexpr std::float_denorm_style has_denorm = std::numeric_limits<self_type>::has_denorm;
static constexpr bool has_infinity = std::numeric_limits<self_type>::has_infinity;
static constexpr bool has_quiet_NaN = std::numeric_limits<self_type>::has_quiet_NaN;
static constexpr bool has_signaling_NaN = std::numeric_limits<self_type>::has_signaling_NaN;
static constexpr bool has_denorm_loss = std::numeric_limits<self_type>::has_denorm_loss;
static constexpr bool traps = std::numeric_limits<self_type>::traps;
static constexpr bool tinyness_before = std::numeric_limits<self_type>::tinyness_before;
static constexpr std::float_round_style round_style = std::numeric_limits<self_type>::round_style;

static constexpr int radix = std::numeric_limits<self_type>::radix;
static constexpr int digits = std::numeric_limits<self_type>::digits;
static constexpr int digits10 = std::numeric_limits<self_type>::digits10;
static constexpr int max_digits10 = std::numeric_limits<self_type>::max_digits10;

static constexpr int max_exponent = std::numeric_limits<self_type>::max_exponent;
static constexpr int min_exponent = std::numeric_limits<self_type>::min_exponent;
static constexpr int max_exponent10 = std::numeric_limits<self_type>::max_exponent10;
static constexpr int min_exponent10 = std::numeric_limits<self_type>::min_exponent10;

static constexpr self_type(min) () noexcept { return (std::numeric_limits<self_type>::min) (); }
static constexpr self_type(max) () noexcept { return (std::numeric_limits<self_type>::max) (); }
static constexpr self_type lowest () noexcept { return std::numeric_limits<self_type>::lowest (); }
static constexpr self_type epsilon () noexcept { return std::numeric_limits<self_type>::epsilon (); }
static constexpr self_type round_error () noexcept { return std::numeric_limits<self_type>::round_error (); }
static constexpr self_type denorm_min () noexcept { return std::numeric_limits<self_type>::denorm_min (); }
static constexpr self_type infinity () noexcept { return std::numeric_limits<self_type>::infinity (); }
static constexpr self_type quiet_NaN () noexcept { return std::numeric_limits<self_type>::quiet_NaN (); }
static constexpr self_type signaling_NaN() noexcept { return std::numeric_limits<self_type>::signaling_NaN(); }
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;

static constexpr float_type(min) () noexcept { return (std::numeric_limits<float_type>::min) (); }
static constexpr float_type(max) () noexcept { return (std::numeric_limits<float_type>::max) (); }
static constexpr float_type lowest () noexcept { return std::numeric_limits<float_type>::lowest (); }
static constexpr float_type epsilon () noexcept { return std::numeric_limits<float_type>::epsilon (); }
static constexpr float_type round_error () noexcept { return std::numeric_limits<float_type>::round_error (); }
static constexpr float_type denorm_min () noexcept { return std::numeric_limits<float_type>::denorm_min (); }
static constexpr float_type infinity () noexcept { return std::numeric_limits<float_type>::infinity (); }
static constexpr float_type quiet_NaN () noexcept { return std::numeric_limits<float_type>::quiet_NaN (); }
static constexpr float_type signaling_NaN() noexcept { return std::numeric_limits<float_type>::signaling_NaN(); }
};

#if defined(BOOST_HAS_FLOAT128)
Expand All @@ -75,7 +75,7 @@ struct numeric_limits<FloatingPointType,
typename std::enable_if<std::is_same<FloatingPointType, ::boost::float128_type>::value>::type>
{
private:
using self_type = ::boost::float128_type;
using float_type = ::boost::float128_type;

public:
static constexpr bool is_specialized = true;
Expand Down Expand Up @@ -104,86 +104,86 @@ struct numeric_limits<FloatingPointType,
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 self_type (min)() noexcept
static constexpr float_type (min)() noexcept
{
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;
return static_cast<float_type>(1)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN) / 1073741824;
}

static constexpr self_type (max)() noexcept
static constexpr float_type (max)() noexcept
{
// 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;
return (static_cast<float_type>(1) - 9.62964972193617926527988971292463659e-35) // This now has all bits sets to 1
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult)
* static_cast<float_type>(dbl_mult) * 65536;
}

static constexpr self_type lowest() noexcept { return -(max)(); }
static constexpr float_type lowest() noexcept { return -(max)(); }

static constexpr self_type epsilon()
static constexpr float_type epsilon()
{
// This double value has only one bit set and so is exact.
return 1.92592994438723585305597794258492732e-34;
}

static constexpr self_type round_error() noexcept { return 0.5; }
static constexpr float_type round_error() noexcept { return 0.5; }

static constexpr self_type denorm_min() noexcept
static constexpr float_type denorm_min() noexcept
{
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)
return static_cast<float_type>(1)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
* static_cast<float_type>(DBL_MIN)
/ 5.5751862996326557854e+42;
}

static constexpr self_type infinity () noexcept { return HUGE_VAL; }
static constexpr self_type quiet_NaN () noexcept { return NAN; }
static constexpr self_type signaling_NaN() noexcept { return 0; }
static constexpr float_type infinity () noexcept { return HUGE_VAL; }
static constexpr float_type quiet_NaN () noexcept { return NAN; }
static constexpr float_type signaling_NaN() noexcept { return 0; }
};
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace detail {
template <class T>
auto log_impl(T x) -> T
{
// Default to the regular std::log function.
// Default to the regular log function.
using std::log;

return log(x);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace detail {
template <class T>
auto sqrt_impl(T x) -> T
{
// Default to the regular std::sqrt function.
// Default to the regular sqrt function.
using std::sqrt;

return sqrt(x);
Expand Down
Loading

0 comments on commit b9ff1a2

Please sign in to comment.