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