Skip to content

Commit ad2db3c

Browse files
committed
Update decimal128_t / and % non-finite value handling
1 parent 5b3aa00 commit ad2db3c

File tree

1 file changed

+73
-51
lines changed

1 file changed

+73
-51
lines changed

include/boost/decimal/decimal128_t.hpp

Lines changed: 73 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1581,67 +1581,85 @@ constexpr auto d128_div_impl(const decimal128_t& lhs, const decimal128_t& rhs, d
15811581
const auto lhs_fp {fpclassify(lhs)};
15821582
const auto rhs_fp {fpclassify(rhs)};
15831583

1584-
if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
1584+
if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL)
15851585
{
1586-
// Operations on an SNAN return a QNAN with the same payload
1587-
decimal128_t return_nan {};
1588-
if (lhs_fp == FP_NAN)
1586+
if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
15891587
{
1590-
return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs;
1591-
}
1592-
else
1593-
{
1594-
return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs;
1595-
}
1596-
1597-
q = return_nan;
1598-
r = return_nan;
1599-
1600-
return;
1601-
}
1602-
1603-
switch (lhs_fp)
1604-
{
1605-
case FP_INFINITE:
1606-
if (rhs_fp == FP_INFINITE)
1607-
{
1608-
q = nan;
1609-
r = nan;
1610-
}
1611-
else
1588+
// Operations on an SNAN return a QNAN with the same payload
1589+
decimal128_t return_nan {};
1590+
if (lhs_fp == rhs_fp)
16121591
{
1613-
q = sign ? -inf : inf;
1614-
r = zero;
1592+
// They are both NANs
1593+
const bool lhs_signaling {issignaling(lhs)};
1594+
const bool rhs_signaling {issignaling(rhs)};
1595+
1596+
if (!lhs_signaling && rhs_signaling)
1597+
{
1598+
return_nan = nan_conversion(rhs);
1599+
}
1600+
else
1601+
{
1602+
return_nan = lhs_signaling ? nan_conversion(lhs) : lhs;
1603+
}
16151604
}
1616-
return;
1617-
case FP_ZERO:
1618-
if (rhs_fp == FP_ZERO)
1605+
else if (lhs_fp == FP_NAN)
16191606
{
1620-
q = nan;
1621-
r = nan;
1607+
return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs;
16221608
}
16231609
else
16241610
{
1625-
q = sign ? -zero : zero;
1626-
r = sign ? -zero : zero;
1611+
return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs;
16271612
}
1628-
return;
1629-
default:
1630-
static_cast<void>(lhs);
1631-
}
16321613

1633-
switch (rhs_fp)
1634-
{
1635-
case FP_ZERO:
1636-
q = inf;
1637-
r = zero;
1638-
return;
1639-
case FP_INFINITE:
1640-
q = sign ? -zero : zero;
1641-
r = lhs;
1614+
q = return_nan;
1615+
r = return_nan;
1616+
16421617
return;
1643-
default:
1644-
static_cast<void>(rhs);
1618+
}
1619+
1620+
switch (lhs_fp)
1621+
{
1622+
case FP_INFINITE:
1623+
if (rhs_fp == FP_INFINITE)
1624+
{
1625+
q = nan;
1626+
r = nan;
1627+
}
1628+
else
1629+
{
1630+
q = sign ? -inf : inf;
1631+
r = zero;
1632+
}
1633+
return;
1634+
case FP_ZERO:
1635+
if (rhs_fp == FP_ZERO)
1636+
{
1637+
q = nan;
1638+
r = nan;
1639+
}
1640+
else
1641+
{
1642+
q = sign ? -zero : zero;
1643+
r = sign ? -zero : zero;
1644+
}
1645+
return;
1646+
default:
1647+
static_cast<void>(lhs);
1648+
}
1649+
1650+
switch (rhs_fp)
1651+
{
1652+
case FP_ZERO:
1653+
q = inf;
1654+
r = zero;
1655+
return;
1656+
case FP_INFINITE:
1657+
q = sign ? -zero : zero;
1658+
r = lhs;
1659+
return;
1660+
default:
1661+
static_cast<void>(rhs);
1662+
}
16451663
}
16461664
#else
16471665
static_cast<void>(r);
@@ -1977,7 +1995,11 @@ constexpr auto operator%(const decimal128_t& lhs, const decimal128_t& rhs) noexc
19771995
decimal128_t q {};
19781996
decimal128_t r {};
19791997
d128_div_impl(lhs, rhs, q, r);
1980-
d128_mod_impl(lhs, rhs, q, r);
1998+
1999+
if (BOOST_DECIMAL_LIKELY(!isnan(q)))
2000+
{
2001+
d128_mod_impl(lhs, rhs, q, r);
2002+
}
19812003

19822004
return r;
19832005
}

0 commit comments

Comments
 (0)