Skip to content

Commit ee6316d

Browse files
committed
Update decimal_fast64_t / and % handling
1 parent 40f21d5 commit ee6316d

File tree

1 file changed

+73
-51
lines changed

1 file changed

+73
-51
lines changed

include/boost/decimal/decimal_fast64_t.hpp

Lines changed: 73 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,67 +1291,85 @@ constexpr auto d64_fast_div_impl(const decimal_fast64_t& lhs, const decimal_fast
12911291
const auto lhs_fp {fpclassify(lhs)};
12921292
const auto rhs_fp {fpclassify(rhs)};
12931293

1294-
if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
1294+
if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL)
12951295
{
1296-
// Operations on an SNAN return a QNAN with the same payload
1297-
decimal_fast64_t return_nan {};
1298-
if (lhs_fp == FP_NAN)
1296+
if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
12991297
{
1300-
return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs;
1301-
}
1302-
else
1303-
{
1304-
return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs;
1305-
}
1306-
1307-
q = return_nan;
1308-
r = return_nan;
1309-
1310-
return;
1311-
}
1312-
1313-
switch (lhs_fp)
1314-
{
1315-
case FP_INFINITE:
1316-
if (rhs_fp == FP_INFINITE)
1298+
// Operations on an SNAN return a QNAN with the same payload
1299+
decimal_fast64_t return_nan {};
1300+
if (lhs_fp == rhs_fp)
13171301
{
1318-
q = nan;
1319-
r = nan;
1302+
// They are both NANs
1303+
const bool lhs_signaling {issignaling(lhs)};
1304+
const bool rhs_signaling {issignaling(rhs)};
1305+
1306+
if (!lhs_signaling && rhs_signaling)
1307+
{
1308+
return_nan = nan_conversion(rhs);
1309+
}
1310+
else
1311+
{
1312+
return_nan = lhs_signaling ? nan_conversion(lhs) : lhs;
1313+
}
13201314
}
1321-
else
1322-
{
1323-
q = sign ? -inf : inf;
1324-
r = zero;
1325-
}
1326-
return;
1327-
case FP_ZERO:
1328-
if (rhs_fp == FP_ZERO)
1315+
else if (lhs_fp == FP_NAN)
13291316
{
1330-
q = nan;
1331-
r = nan;
1317+
return_nan = issignaling(lhs) ? nan_conversion(lhs) : lhs;
13321318
}
13331319
else
13341320
{
1335-
q = sign ? -zero : zero;
1336-
r = sign ? -zero : zero;
1321+
return_nan = issignaling(rhs) ? nan_conversion(rhs) : rhs;
13371322
}
1338-
return;
1339-
default:
1340-
static_cast<void>(lhs);
1341-
}
13421323

1343-
switch (rhs_fp)
1344-
{
1345-
case FP_ZERO:
1346-
q = inf;
1347-
r = zero;
1348-
return;
1349-
case FP_INFINITE:
1350-
q = sign ? -zero : zero;
1351-
r = lhs;
1324+
q = return_nan;
1325+
r = return_nan;
1326+
13521327
return;
1353-
default:
1354-
static_cast<void>(rhs);
1328+
}
1329+
1330+
switch (lhs_fp)
1331+
{
1332+
case FP_INFINITE:
1333+
if (rhs_fp == FP_INFINITE)
1334+
{
1335+
q = nan;
1336+
r = nan;
1337+
}
1338+
else
1339+
{
1340+
q = sign ? -inf : inf;
1341+
r = zero;
1342+
}
1343+
return;
1344+
case FP_ZERO:
1345+
if (rhs_fp == FP_ZERO)
1346+
{
1347+
q = nan;
1348+
r = nan;
1349+
}
1350+
else
1351+
{
1352+
q = sign ? -zero : zero;
1353+
r = sign ? -zero : zero;
1354+
}
1355+
return;
1356+
default:
1357+
static_cast<void>(lhs);
1358+
}
1359+
1360+
switch (rhs_fp)
1361+
{
1362+
case FP_ZERO:
1363+
q = inf;
1364+
r = zero;
1365+
return;
1366+
case FP_INFINITE:
1367+
q = sign ? -zero : zero;
1368+
r = lhs;
1369+
return;
1370+
default:
1371+
static_cast<void>(rhs);
1372+
}
13551373
}
13561374
#else
13571375
static_cast<void>(r);
@@ -1483,7 +1501,11 @@ constexpr auto operator%(const decimal_fast64_t lhs, const decimal_fast64_t rhs)
14831501
decimal_fast64_t q {};
14841502
decimal_fast64_t r {};
14851503
d64_fast_div_impl(lhs, rhs, q, r);
1486-
d64_fast_mod_impl(lhs, rhs, q, r);
1504+
1505+
if (BOOST_DECIMAL_LIKELY(!isnan(q)))
1506+
{
1507+
d64_fast_mod_impl(lhs, rhs, q, r);
1508+
}
14871509

14881510
return r;
14891511
}

0 commit comments

Comments
 (0)