@@ -1166,67 +1166,85 @@ constexpr auto div_impl(const decimal_fast32_t lhs, const decimal_fast32_t rhs,
11661166 const auto lhs_fp {fpclassify (lhs)};
11671167 const auto rhs_fp {fpclassify (rhs)};
11681168
1169- if (lhs_fp == FP_NAN || rhs_fp == FP_NAN )
1169+ if (lhs_fp != FP_NORMAL || rhs_fp != FP_NORMAL )
11701170 {
1171- // Operations on an SNAN return a QNAN with the same payload
1172- decimal_fast32_t return_nan {};
1173- if (lhs_fp == FP_NAN)
1171+ if (lhs_fp == FP_NAN || rhs_fp == FP_NAN)
11741172 {
1175- return_nan = issignaling (lhs) ? nan_conversion (lhs) : lhs;
1176- }
1177- else
1178- {
1179- return_nan = issignaling (rhs) ? nan_conversion (rhs) : rhs;
1180- }
1181-
1182- q = return_nan;
1183- r = return_nan;
1184-
1185- return ;
1186- }
1187-
1188- switch (lhs_fp)
1189- {
1190- case FP_INFINITE:
1191- if (rhs_fp == FP_INFINITE)
1173+ // Operations on an SNAN return a QNAN with the same payload
1174+ decimal_fast32_t return_nan {};
1175+ if (lhs_fp == rhs_fp)
11921176 {
1193- q = nan;
1194- r = nan;
1177+ // They are both NANs
1178+ const bool lhs_signaling {issignaling (lhs)};
1179+ const bool rhs_signaling {issignaling (rhs)};
1180+
1181+ if (!lhs_signaling && rhs_signaling)
1182+ {
1183+ return_nan = nan_conversion (rhs);
1184+ }
1185+ else
1186+ {
1187+ return_nan = lhs_signaling ? nan_conversion (lhs) : lhs;
1188+ }
11951189 }
1196- else
1197- {
1198- q = sign ? -inf : inf;
1199- r = zero;
1200- }
1201- return ;
1202- case FP_ZERO:
1203- if (rhs_fp == FP_ZERO)
1190+ else if (lhs_fp == FP_NAN)
12041191 {
1205- q = nan;
1206- r = nan;
1192+ return_nan = issignaling (lhs) ? nan_conversion (lhs) : lhs;
12071193 }
12081194 else
12091195 {
1210- q = sign ? -zero : zero;
1211- r = sign ? -zero : zero;
1196+ return_nan = issignaling (rhs) ? nan_conversion (rhs) : rhs;
12121197 }
1213- return ;
1214- default :
1215- static_cast <void >(lhs);
1216- }
12171198
1218- switch (rhs_fp)
1219- {
1220- case FP_ZERO:
1221- q = inf;
1222- r = zero;
1223- return ;
1224- case FP_INFINITE:
1225- q = sign ? -zero : zero;
1226- r = lhs;
1199+ q = return_nan;
1200+ r = return_nan;
1201+
12271202 return ;
1228- default :
1229- static_cast <void >(rhs);
1203+ }
1204+
1205+ switch (lhs_fp)
1206+ {
1207+ case FP_INFINITE:
1208+ if (rhs_fp == FP_INFINITE)
1209+ {
1210+ q = nan;
1211+ r = nan;
1212+ }
1213+ else
1214+ {
1215+ q = sign ? -inf : inf;
1216+ r = zero;
1217+ }
1218+ return ;
1219+ case FP_ZERO:
1220+ if (rhs_fp == FP_ZERO)
1221+ {
1222+ q = nan;
1223+ r = nan;
1224+ }
1225+ else
1226+ {
1227+ q = sign ? -zero : zero;
1228+ r = sign ? -zero : zero;
1229+ }
1230+ return ;
1231+ default :
1232+ static_cast <void >(lhs);
1233+ }
1234+
1235+ switch (rhs_fp)
1236+ {
1237+ case FP_ZERO:
1238+ q = inf;
1239+ r = zero;
1240+ return ;
1241+ case FP_INFINITE:
1242+ q = sign ? -zero : zero;
1243+ r = lhs;
1244+ return ;
1245+ default :
1246+ static_cast <void >(rhs);
1247+ }
12301248 }
12311249 #else
12321250 static_cast <void >(r);
@@ -1334,7 +1352,11 @@ constexpr auto operator%(const decimal_fast32_t lhs, const decimal_fast32_t rhs)
13341352 decimal_fast32_t q {};
13351353 decimal_fast32_t r {};
13361354 div_impl (lhs, rhs, q, r);
1337- mod_impl (lhs, rhs, q, r);
1355+
1356+ if (BOOST_DECIMAL_LIKELY (!isnan (q)))
1357+ {
1358+ mod_impl (lhs, rhs, q, r);
1359+ }
13381360
13391361 return r;
13401362}
0 commit comments