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