Skip to content

Commit 7a727a7

Browse files
authored
Merge pull request #1255 from cppalliance/1254
2 parents 9051a03 + 5881278 commit 7a727a7

File tree

8 files changed

+508
-309
lines changed

8 files changed

+508
-309
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
}

include/boost/decimal/decimal32_t.hpp

Lines changed: 74 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,68 +1896,86 @@ constexpr auto div_impl(const decimal32_t lhs, const decimal32_t rhs, decimal32_
18961896

18971897
const auto lhs_fp {fpclassify(lhs)};
18981898
const auto rhs_fp {fpclassify(rhs)};
1899-
1900-
if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
1901-
{
1902-
// Operations on an SNAN return a QNAN with the same payload
1903-
decimal32_t return_nan {};
1904-
if (lhs_fp == FP_NAN)
1905-
{
1906-
return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs;
1907-
}
1908-
else
1909-
{
1910-
return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs;
1911-
}
1912-
1913-
q = return_nan;
1914-
r = return_nan;
19151899

1916-
return;
1917-
}
1918-
1919-
switch (lhs_fp)
1900+
if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL)
19201901
{
1921-
case FP_INFINITE:
1922-
if (rhs_fp == FP_INFINITE)
1923-
{
1924-
q = nan;
1925-
r = nan;
1926-
}
1927-
else
1902+
if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
1903+
{
1904+
// Operations on an SNAN return a QNAN with the same payload
1905+
decimal32_t return_nan {};
1906+
if (lhs_fp == rhs_fp)
19281907
{
1929-
q = sign ? -inf : inf;
1930-
r = zero;
1908+
// They are both NANs
1909+
const bool lhs_signaling {issignaling(lhs)};
1910+
const bool rhs_signaling {issignaling(rhs)};
1911+
1912+
if (!lhs_signaling && rhs_signaling)
1913+
{
1914+
return_nan = nan_conversion(rhs);
1915+
}
1916+
else
1917+
{
1918+
return_nan = lhs_signaling ? nan_conversion(lhs) : lhs;
1919+
}
19311920
}
1932-
return;
1933-
case FP_ZERO:
1934-
if (rhs_fp == FP_ZERO)
1921+
else if (lhs_fp == FP_NAN)
19351922
{
1936-
q = nan;
1937-
r = nan;
1923+
return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs;
19381924
}
19391925
else
19401926
{
1941-
q = sign ? -zero : zero;
1942-
r = sign ? -zero : zero;
1927+
return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs;
19431928
}
1944-
return;
1945-
default:
1946-
static_cast<void>(lhs);
1947-
}
19481929

1949-
switch (rhs_fp)
1950-
{
1951-
case FP_ZERO:
1952-
q = inf;
1953-
r = zero;
1954-
return;
1955-
case FP_INFINITE:
1956-
q = sign ? -zero : zero;
1957-
r = lhs;
1930+
q = return_nan;
1931+
r = return_nan;
1932+
19581933
return;
1959-
default:
1960-
static_cast<void>(rhs);
1934+
}
1935+
1936+
switch (lhs_fp)
1937+
{
1938+
case FP_INFINITE:
1939+
if (rhs_fp == FP_INFINITE)
1940+
{
1941+
q = nan;
1942+
r = nan;
1943+
}
1944+
else
1945+
{
1946+
q = sign ? -inf : inf;
1947+
r = zero;
1948+
}
1949+
return;
1950+
case FP_ZERO:
1951+
if (rhs_fp == FP_ZERO)
1952+
{
1953+
q = nan;
1954+
r = nan;
1955+
}
1956+
else
1957+
{
1958+
q = sign ? -zero : zero;
1959+
r = sign ? -zero : zero;
1960+
}
1961+
return;
1962+
default:
1963+
static_cast<void>(lhs);
1964+
}
1965+
1966+
switch (rhs_fp)
1967+
{
1968+
case FP_ZERO:
1969+
q = inf;
1970+
r = zero;
1971+
return;
1972+
case FP_INFINITE:
1973+
q = sign ? -zero : zero;
1974+
r = lhs;
1975+
return;
1976+
default:
1977+
static_cast<void>(rhs);
1978+
}
19611979
}
19621980
#else
19631981
static_cast<void>(r);
@@ -2115,7 +2133,11 @@ constexpr auto operator%(const decimal32_t lhs, const decimal32_t rhs) noexcept
21152133
decimal32_t q {};
21162134
decimal32_t r {};
21172135
div_impl(lhs, rhs, q, r);
2118-
mod_impl(lhs, rhs, q, r);
2136+
2137+
if (BOOST_DECIMAL_LIKELY(!isnan(q)))
2138+
{
2139+
mod_impl(lhs, rhs, q, r);
2140+
}
21192141

21202142
return r;
21212143
}

0 commit comments

Comments
 (0)