Skip to content

Commit 2bb13b7

Browse files
committed
Extract values of non-finites
1 parent a9aae9b commit 2bb13b7

File tree

1 file changed

+35
-14
lines changed

1 file changed

+35
-14
lines changed

include/boost/decimal/gcc_decimal32.hpp

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t gccd32_11_significand_mask = UINT
7171

7272
#endif
7373

74+
// Non-finite values
75+
BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t gccd32_inf = UINT32_C(0x78000000);
76+
BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t gccd32_qnan = UINT32_C(0x7C000000);
77+
BOOST_DECIMAL_CONSTEXPR_VARIABLE std::uint32_t gccd32_snan = UINT32_C(0x7E000000);
78+
7479
} // namespace detail
7580

7681
// This type is a wrapper around gcc std::decimal::decimal32 to allow it to use
@@ -327,28 +332,28 @@ BOOST_DECIMAL_EXPORT class gcc_decimal32 final
327332

328333
template <typename Integer>
329334
inline auto operator+=(Integer rhs) noexcept
330-
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32&)
335+
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, gcc_decimal32&)
331336
{ internal_decimal_ += rhs; return *this; }
332337

333338
inline auto operator-=(gcc_decimal32 rhs) noexcept -> gcc_decimal32&
334339
{ internal_decimal_ -= rhs.underlying(); return *this; }
335340

336341
template <typename Integer>
337342
inline auto operator-=(Integer rhs) noexcept
338-
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32&)
343+
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, gcc_decimal32&)
339344
{ internal_decimal_ -= rhs; return *this; }
340345

341346
template <typename Integer>
342347
inline auto operator*=(Integer rhs) noexcept
343-
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32&)
348+
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, gcc_decimal32&)
344349
{ internal_decimal_ *= rhs; return *this; }
345350

346351
inline auto operator*=(gcc_decimal32 rhs) noexcept -> gcc_decimal32&
347352
{ internal_decimal_ *= rhs.underlying(); return *this; }
348353

349354
template <typename Integer>
350355
inline auto operator/=(Integer rhs) noexcept
351-
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, decimal32&)
356+
BOOST_DECIMAL_REQUIRES_RETURN(detail::is_integral_v, Integer, gcc_decimal32&)
352357
{ internal_decimal_ /= rhs; return *this; }
353358

354359
inline auto operator/=(gcc_decimal32 rhs) noexcept -> gcc_decimal32&
@@ -505,32 +510,48 @@ inline auto signbit BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (gcc_decimal32 rhs)
505510

506511
inline auto isinf BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (gcc_decimal32 rhs) noexcept -> bool
507512
{
508-
static_cast<void>(rhs);
509-
return false;
513+
std::uint32_t bits_ {};
514+
std::memcpy(&bits_, &rhs.internal_decimal_, sizeof(std::uint32_t));
515+
516+
return bits_ == detail::gccd32_inf;
510517
}
511518

512519
inline auto isnan BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (gcc_decimal32 rhs) noexcept -> bool
513520
{
514-
static_cast<void>(rhs);
515-
return false;
521+
std::uint32_t bits_ {};
522+
std::memcpy(&bits_, &rhs.internal_decimal_, sizeof(std::uint32_t));
523+
524+
return bits_ >= detail::gccd32_qnan;
516525
}
517526

518527
inline auto issignaling BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (gcc_decimal32 rhs) noexcept -> bool
519528
{
520-
static_cast<void>(rhs);
521-
return false;
529+
std::uint32_t bits_ {};
530+
std::memcpy(&bits_, &rhs.internal_decimal_, sizeof(std::uint32_t));
531+
532+
return bits_ == detail::gccd32_snan;
522533
}
523534

524535
inline auto isfinite BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (gcc_decimal32 rhs) noexcept -> bool
525536
{
526-
static_cast<void>(rhs);
527-
return true;
537+
std::uint32_t bits_ {};
538+
std::memcpy(&bits_, &rhs.internal_decimal_, sizeof(std::uint32_t));
539+
540+
return bits_ < detail::gccd32_inf;
528541
}
529542

530543
inline auto isnormal BOOST_DECIMAL_PREVENT_MACRO_SUBSTITUTION (gcc_decimal32 rhs) noexcept -> bool
531544
{
532-
static_cast<void>(rhs);
533-
return true;
545+
// Check for de-normals
546+
const auto sig {rhs.full_significand()};
547+
const auto exp {rhs.unbiased_exponent()};
548+
549+
if (exp <= detail::precision_v<decimal32> - 1)
550+
{
551+
return false;
552+
}
553+
554+
return (sig != 0) && isfinite(rhs);
534555
}
535556

536557
inline gcc_decimal32::operator unsigned long long() const noexcept

0 commit comments

Comments
 (0)