@@ -1198,68 +1198,86 @@ constexpr auto d128f_div_impl(const decimal_fast128_t& lhs, const decimal_fast12
11981198 const auto lhs_fp {fpclassify (lhs)};
11991199 const auto rhs_fp {fpclassify (rhs)};
12001200
1201- // NAN has to come first
1202- if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
1201+ if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL)
12031202 {
1204- // Operations on an SNAN return a QNAN with the same payload
1205- decimal_fast128_t return_nan {};
1206- if (lhs_fp == FP_NAN)
1203+ // NAN has to come first
1204+ if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
12071205 {
1208- return_nan = issignaling (lhs) ? nan_conversion (lhs) : lhs;
1209- }
1210- else
1211- {
1212- return_nan = issignaling (rhs) ? nan_conversion (rhs) : rhs;
1213- }
1214-
1215- q = return_nan;
1216- r = return_nan;
1217-
1218- return ;
1219- }
1220-
1221- switch (lhs_fp)
1222- {
1223- case FP_INFINITE:
1224- if (rhs_fp == FP_INFINITE)
1206+ // Operations on an SNAN return a QNAN with the same payload
1207+ decimal_fast128_t return_nan {};
1208+ if (lhs_fp == rhs_fp)
12251209 {
1226- q = nan;
1227- r = nan;
1210+ // They are both NANs
1211+ const bool lhs_signaling {issignaling (lhs)};
1212+ const bool rhs_signaling {issignaling (rhs)};
1213+
1214+ if (!lhs_signaling && rhs_signaling)
1215+ {
1216+ return_nan = nan_conversion (rhs);
1217+ }
1218+ else
1219+ {
1220+ return_nan = lhs_signaling ? nan_conversion (lhs) : lhs;
1221+ }
12281222 }
1229- else
1230- {
1231- q = sign ? -inf : inf;
1232- r = zero;
1233- }
1234- return ;
1235- case FP_ZERO:
1236- if (rhs_fp == FP_ZERO)
1223+ else if (lhs_fp == FP_NAN)
12371224 {
1238- q = nan;
1239- r = nan;
1225+ return_nan = issignaling (lhs) ? nan_conversion (lhs) : lhs;
12401226 }
12411227 else
12421228 {
1243- q = sign ? -zero : zero;
1244- r = sign ? -zero : zero;
1229+ return_nan = issignaling (rhs) ? nan_conversion (rhs) : rhs;
12451230 }
1246- return ;
1247- default :
1248- static_cast <void >(lhs);
1249- }
12501231
1251- switch (rhs_fp)
1252- {
1253- case FP_ZERO:
1254- q = inf;
1255- r = zero;
1256- return ;
1257- case FP_INFINITE:
1258- q = sign ? -zero : zero;
1259- r = lhs;
1232+ q = return_nan;
1233+ r = return_nan;
1234+
12601235 return ;
1261- default :
1262- static_cast <void >(rhs);
1236+ }
1237+
1238+ switch (lhs_fp)
1239+ {
1240+ case FP_INFINITE:
1241+ if (rhs_fp == FP_INFINITE)
1242+ {
1243+ q = nan;
1244+ r = nan;
1245+ }
1246+ else
1247+ {
1248+ q = sign ? -inf : inf;
1249+ r = zero;
1250+ }
1251+ return ;
1252+ case FP_ZERO:
1253+ if (rhs_fp == FP_ZERO)
1254+ {
1255+ q = nan;
1256+ r = nan;
1257+ }
1258+ else
1259+ {
1260+ q = sign ? -zero : zero;
1261+ r = sign ? -zero : zero;
1262+ }
1263+ return ;
1264+ default :
1265+ static_cast <void >(lhs);
1266+ }
1267+
1268+ switch (rhs_fp)
1269+ {
1270+ case FP_ZERO:
1271+ q = inf;
1272+ r = zero;
1273+ return ;
1274+ case FP_INFINITE:
1275+ q = sign ? -zero : zero;
1276+ r = lhs;
1277+ return ;
1278+ default :
1279+ static_cast <void >(rhs);
1280+ }
12631281 }
12641282 #else
12651283 static_cast <void >(r);
@@ -1380,7 +1398,11 @@ constexpr auto operator%(const decimal_fast128_t& lhs, const decimal_fast128_t&
13801398 decimal_fast128_t q {};
13811399 decimal_fast128_t r {};
13821400 d128f_div_impl (lhs, rhs, q, r);
1383- d128f_mod_impl (lhs, rhs, q, r);
1401+
1402+ if (BOOST_DECIMAL_LIKELY (!isnan (q)))
1403+ {
1404+ d128f_mod_impl (lhs, rhs, q, r);
1405+ }
13841406
13851407 return r;
13861408};
0 commit comments