Skip to content

Commit

Permalink
Merge pull request #749 from cppalliance/fast_cmath
Browse files Browse the repository at this point in the history
Add additional fast math support
  • Loading branch information
mborland authored Oct 4, 2024
2 parents d2d488c + 1af115d commit c21c6b7
Show file tree
Hide file tree
Showing 52 changed files with 414 additions and 13 deletions.
29 changes: 29 additions & 0 deletions include/boost/decimal/decimal128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1122,21 +1122,37 @@ constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128 rhs)

constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return (rhs.bits_.high & detail::d128_nan_mask_high_bits) == detail::d128_nan_mask_high_bits;
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return (rhs.bits_.high & detail::d128_nan_mask_high_bits) == detail::d128_inf_mask_high_bits;
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return (rhs.bits_.high & detail::d128_snan_mask_high_bits) == detail::d128_snan_mask_high_bits;
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
// Check for de-normals
const auto sig {rhs.full_significand()};
const auto exp {rhs.unbiased_exponent()};
Expand All @@ -1147,16 +1163,29 @@ constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128 rhs
}

return (sig != 0) && isfinite(rhs);
#else
return rhs.full_significand() != 0;
#endif
}

constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal128 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return (rhs.bits_.high & detail::d128_inf_mask_high_bits) != detail::d128_inf_mask_high_bits;
#else
static_cast<void>(rhs);
return true;
#endif
}

constexpr auto not_finite(decimal128 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return (rhs.bits_.high & detail::d128_inf_mask_high_bits) == detail::d128_inf_mask_high_bits;
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto operator+(decimal128 rhs) noexcept -> decimal128
Expand Down
29 changes: 29 additions & 0 deletions include/boost/decimal/decimal128_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,37 +468,66 @@ constexpr auto signbit(decimal128_fast val) noexcept -> bool

constexpr auto isinf(decimal128_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_.high == detail::d128_fast_inf_high_bits;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto isnan(decimal128_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_.high >= detail::d128_fast_qnan_high_bits;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto issignaling(decimal128_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_.high == detail::d128_fast_snan_high_bits;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto isnormal(decimal128_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
if (val.exponent_ <= static_cast<decimal128_fast::exponent_type>(detail::precision_v<decimal128> - 1))
{
return false;
}

return (val.significand_ != 0) && isfinite(val);
#else
return val.significand_ != 0;
#endif
}

constexpr auto isfinite(decimal128_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_.high < detail::d128_fast_inf_high_bits;
#else
static_cast<void>(val);
return true;
#endif
}

constexpr auto not_finite(const decimal128_fast& val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_.high >= detail::d128_fast_inf_high_bits;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto operator==(const decimal128_fast& lhs, const decimal128_fast& rhs) noexcept -> bool
Expand Down
24 changes: 24 additions & 0 deletions include/boost/decimal/decimal32.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -805,26 +805,47 @@ constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32 rhs)

constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return (rhs.bits_ & detail::d32_nan_mask) == detail::d32_nan_mask;
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return (rhs.bits_ & detail::d32_snan_mask) == detail::d32_snan_mask;
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return ((rhs.bits_ & detail::d32_nan_mask) == detail::d32_inf_mask);
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return ((rhs.bits_ & detail::d32_inf_mask) != detail::d32_inf_mask);
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
// Check for de-normals
const auto sig {rhs.full_significand()};
const auto exp {rhs.unbiased_exponent()};
Expand All @@ -835,6 +856,9 @@ constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal32 rhs)
}

return (sig != 0) && isfinite(rhs);
#else
return rhs.full_significand() != 0;
#endif
}

constexpr auto operator+(decimal32 rhs) noexcept -> decimal32
Expand Down
21 changes: 20 additions & 1 deletion include/boost/decimal/decimal32_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,22 +453,41 @@ constexpr auto signbit(decimal32_fast val) noexcept -> bool

constexpr auto isinf(decimal32_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_ == detail::d32_fast_inf;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto isnan(decimal32_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_ == detail::d32_fast_qnan || val.significand_ == detail::d32_fast_snan;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto issignaling(decimal32_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_ == detail::d32_fast_snan;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto isnormal(decimal32_fast val) noexcept -> bool
{
return (val.significand_ != 0) && isfinite(val) && (val.exponent_ > static_cast<std::uint8_t>(detail::precision_v<decimal32> - 1));
return (val.significand_ != 0)
#ifndef BOOST_DECIMAL_FAST_MATH
&& isfinite(val) && (val.exponent_ > static_cast<std::uint8_t>(detail::precision_v<decimal32> - 1))
#endif
;
}

constexpr auto isfinite(decimal32_fast val) noexcept -> bool
Expand Down
29 changes: 29 additions & 0 deletions include/boost/decimal/decimal64.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1082,21 +1082,37 @@ constexpr auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64 rhs)

constexpr auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return (rhs.bits_ & detail::d64_nan_mask) == detail::d64_nan_mask;
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return ((rhs.bits_ & detail::d64_nan_mask) == detail::d64_inf_mask);
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return (rhs.bits_ & detail::d64_snan_mask) == detail::d64_snan_mask;
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
// Check for de-normals
const auto sig {rhs.full_significand()};
const auto exp {rhs.unbiased_exponent()};
Expand All @@ -1107,16 +1123,29 @@ constexpr auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64 rhs)
}

return (sig != 0) && isfinite(rhs);
#else
return rhs.full_significand() != 0;
#endif
}

constexpr auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (decimal64 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return ((rhs.bits_ & detail::d64_inf_mask) != detail::d64_inf_mask);
#else
static_cast<void>(rhs);
return true;
#endif
}

constexpr auto not_finite(decimal64 rhs) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return ((rhs.bits_ & detail::d64_inf_mask) == detail::d64_inf_mask);
#else
static_cast<void>(rhs);
return false;
#endif
}

constexpr auto operator+(decimal64 rhs) noexcept -> decimal64
Expand Down
19 changes: 19 additions & 0 deletions include/boost/decimal/decimal64_fast.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,28 +458,47 @@ constexpr auto signbit(decimal64_fast val) noexcept -> bool

constexpr auto isinf(decimal64_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_ == detail::d64_fast_inf;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto isnan(decimal64_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_ == detail::d64_fast_qnan ||
val.significand_ == detail::d64_fast_snan;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto issignaling(decimal64_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
return val.significand_ == detail::d64_fast_snan;
#else
static_cast<void>(val);
return false;
#endif
}

constexpr auto isnormal(decimal64_fast val) noexcept -> bool
{
#ifndef BOOST_DECIMAL_FAST_MATH
if (val.exponent_ <= static_cast<decimal64_fast::exponent_type>(detail::precision_v<decimal64> - 1))
{
return false;
}

return (val.significand_ != 0) && isfinite(val);
#else
return val.significand_ != 0;
#endif
}

constexpr auto isfinite(decimal64_fast val) noexcept -> bool
Expand Down
2 changes: 2 additions & 0 deletions include/boost/decimal/detail/cmath/acos.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ template <typename T>
constexpr auto acos_impl(T x) noexcept
BOOST_DECIMAL_REQUIRES(detail::is_decimal_floating_point_v, T)
{
#ifndef BOOST_DECIMAL_FAST_MATH
if (isnan(x))
{
return x;
}
#endif

constexpr auto half_pi {numbers::pi_v<T> / 2};
const auto absx {fabs(static_cast<T>(x))};
Expand Down
7 changes: 7 additions & 0 deletions include/boost/decimal/detail/cmath/acosh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ constexpr auto acosh_impl(T x) noexcept

T result { };

#ifndef BOOST_DECIMAL_FAST_MATH
if (fpc != FP_NORMAL)
{
if ((fpc == FP_INFINITE) && (!signbit(x)))
Expand All @@ -45,6 +46,12 @@ constexpr auto acosh_impl(T x) noexcept
result = x;
}
}
#else
if (fpc == FP_ZERO)
{
result = T{0, 0};
}
#endif
else
{
constexpr T one { 1, 0 };
Expand Down
Loading

0 comments on commit c21c6b7

Please sign in to comment.