@@ -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