Skip to content

Commit 40f21d5

Browse files
committed
Update decimal_fast32_t / and % non-finite values handling
1 parent ad2db3c commit 40f21d5

File tree

1 file changed

+73
-51
lines changed

1 file changed

+73
-51
lines changed

include/boost/decimal/decimal_fast32_t.hpp

Lines changed: 73 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)