Skip to content

Commit 367ba35

Browse files
committed
Fix incorrect rounding with subnormal/zero results of float multiplication
1 parent 7a84ce4 commit 367ba35

File tree

2 files changed

+12
-20
lines changed

2 files changed

+12
-20
lines changed

src/float/mul.rs

+7-12
Original file line numberDiff line numberDiff line change
@@ -149,18 +149,13 @@ where
149149
}
150150

151151
// Otherwise, shift the significand of the result so that the round
152-
// bit is the high bit of productLo.
153-
if shift < bits {
154-
let sticky = product_low << (bits - shift);
155-
product_low = product_high << (bits - shift) | product_low >> shift | sticky;
156-
product_high >>= shift;
157-
} else if shift < (2 * bits) {
158-
let sticky = product_high << (2 * bits - shift) | product_low;
159-
product_low = product_high >> (shift - bits) | sticky;
160-
product_high = zero;
161-
} else {
162-
product_high = zero;
163-
}
152+
// bit is the high bit of `product_low`.
153+
// Ensure one of the non-highest bits in `product_low` is set if the shifted out bit are
154+
// not all zero so that the result is correctly rounded below.
155+
let sticky = product_low << (bits - shift) != zero;
156+
product_low =
157+
product_high << (bits - shift) | product_low >> shift | (sticky as u32).cast();
158+
product_high >>= shift;
164159
} else {
165160
// Result is normal before rounding; insert the exponent.
166161
product_high &= significand_mask;

testcrate/tests/mul.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -107,14 +107,11 @@ macro_rules! float_mul {
107107
fuzz_float_2(N, |x: $f, y: $f| {
108108
let mul0 = apfloat_fallback!($f, $apfloat_ty, $sys_available, Mul::mul, x, y);
109109
let mul1: $f = $fn(x, y);
110-
// multiplication of subnormals is not currently handled
111-
if !(Float::is_subnormal(mul0) || Float::is_subnormal(mul1)) {
112-
if !Float::eq_repr(mul0, mul1) {
113-
panic!(
114-
"{}({:?}, {:?}): std: {:?}, builtins: {:?}",
115-
stringify!($fn), x, y, mul0, mul1
116-
);
117-
}
110+
if !Float::eq_repr(mul0, mul1) {
111+
panic!(
112+
"{}({:?}, {:?}): std: {:?}, builtins: {:?}",
113+
stringify!($fn), x, y, mul0, mul1
114+
);
118115
}
119116
});
120117
}

0 commit comments

Comments
 (0)