Skip to content

Commit 5b3aa00

Browse files
committed
Update decimal64_t / and % non-finite value handling
1 parent 8dd52e5 commit 5b3aa00

File tree

1 file changed

+73
-51
lines changed

1 file changed

+73
-51
lines changed

include/boost/decimal/decimal64_t.hpp

Lines changed: 73 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,67 +1568,85 @@ constexpr auto d64_div_impl(const decimal64_t lhs, const decimal64_t rhs, decima
15681568
const auto lhs_fp {fpclassify(lhs)};
15691569
const auto rhs_fp {fpclassify(rhs)};
15701570

1571-
if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
1571+
if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL)
15721572
{
1573-
// Operations on an SNAN return a QNAN with the same payload
1574-
decimal64_t return_nan {};
1575-
if (lhs_fp == FP_NAN)
1573+
if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
15761574
{
1577-
return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs;
1578-
}
1579-
else
1580-
{
1581-
return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs;
1582-
}
1583-
1584-
q = return_nan;
1585-
r = return_nan;
1586-
1587-
return;
1588-
}
1589-
1590-
switch (lhs_fp)
1591-
{
1592-
case FP_INFINITE:
1593-
if (lhs_fp == FP_INFINITE)
1594-
{
1595-
q = nan;
1596-
r = nan;
1597-
}
1598-
else
1575+
// Operations on an SNAN return a QNAN with the same payload
1576+
decimal64_t return_nan {};
1577+
if (lhs_fp == rhs_fp)
15991578
{
1600-
q = sign ? -inf : inf;
1601-
r = zero;
1579+
// They are both NANs
1580+
const bool lhs_signaling {issignaling(lhs)};
1581+
const bool rhs_signaling {issignaling(rhs)};
1582+
1583+
if (!lhs_signaling && rhs_signaling)
1584+
{
1585+
return_nan = nan_conversion(rhs);
1586+
}
1587+
else
1588+
{
1589+
return_nan = lhs_signaling ? nan_conversion(lhs) : lhs;
1590+
}
16021591
}
1603-
return;
1604-
case FP_ZERO:
1605-
if (rhs_fp == FP_ZERO)
1592+
else if (lhs_fp == FP_NAN)
16061593
{
1607-
q = nan;
1608-
r = nan;
1594+
return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs;
16091595
}
16101596
else
16111597
{
1612-
q = sign ? -zero : zero;
1613-
r = sign ? -zero : zero;
1598+
return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs;
16141599
}
1615-
return;
1616-
default:
1617-
static_cast<void>(lhs);
1618-
}
16191600

1620-
switch (rhs_fp)
1621-
{
1622-
case FP_ZERO:
1623-
q = inf;
1624-
r = zero;
1625-
return;
1626-
case FP_INFINITE:
1627-
q = sign ? -zero : zero;
1628-
r = lhs;
1601+
q = return_nan;
1602+
r = return_nan;
1603+
16291604
return;
1630-
default:
1631-
static_cast<void>(rhs);
1605+
}
1606+
1607+
switch (lhs_fp)
1608+
{
1609+
case FP_INFINITE:
1610+
if (lhs_fp == FP_INFINITE)
1611+
{
1612+
q = nan;
1613+
r = nan;
1614+
}
1615+
else
1616+
{
1617+
q = sign ? -inf : inf;
1618+
r = zero;
1619+
}
1620+
return;
1621+
case FP_ZERO:
1622+
if (rhs_fp == FP_ZERO)
1623+
{
1624+
q = nan;
1625+
r = nan;
1626+
}
1627+
else
1628+
{
1629+
q = sign ? -zero : zero;
1630+
r = sign ? -zero : zero;
1631+
}
1632+
return;
1633+
default:
1634+
static_cast<void>(lhs);
1635+
}
1636+
1637+
switch (rhs_fp)
1638+
{
1639+
case FP_ZERO:
1640+
q = inf;
1641+
r = zero;
1642+
return;
1643+
case FP_INFINITE:
1644+
q = sign ? -zero : zero;
1645+
r = lhs;
1646+
return;
1647+
default:
1648+
static_cast<void>(rhs);
1649+
}
16321650
}
16331651

16341652
#else
@@ -1956,7 +1974,11 @@ constexpr auto operator%(const decimal64_t lhs, const decimal64_t rhs) noexcept
19561974
decimal64_t q {};
19571975
decimal64_t r {};
19581976
d64_div_impl(lhs, rhs, q, r);
1959-
d64_mod_impl(lhs, rhs, q, r);
1977+
1978+
if (BOOST_DECIMAL_LIKELY(!isnan(q)))
1979+
{
1980+
d64_mod_impl(lhs, rhs, q, r);
1981+
}
19601982

19611983
return r;
19621984
}

0 commit comments

Comments
 (0)