Skip to content
This repository was archived by the owner on Apr 28, 2025. It is now read-only.

Commit c2d22bf

Browse files
authored
Merge pull request #252 from jethrogb/issue-242
Fix substract with borrow in FMA
2 parents d39a3d8 + 8f10cf5 commit c2d22bf

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

src/math/fma.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,9 @@ pub fn fma(x: f64, y: f64, z: f64) -> f64 {
122122
rhi += zhi + (rlo < zlo) as u64;
123123
} else {
124124
/* r -= z */
125-
let t = rlo;
126-
rlo = rlo.wrapping_sub(zlo);
127-
rhi = rhi.wrapping_sub(zhi.wrapping_sub((t < rlo) as u64));
125+
let (res, borrow) = rlo.overflowing_sub(zlo);
126+
rlo = res;
127+
rhi = rhi.wrapping_sub(zhi.wrapping_add(borrow as u64));
128128
if (rhi >> 63) != 0 {
129129
rlo = (-(rlo as i64)) as u64;
130130
rhi = (-(rhi as i64)) as u64 - (rlo != 0) as u64;
@@ -218,6 +218,14 @@ mod tests {
218218
-0.00000000000000022204460492503126,
219219
);
220220

221-
assert_eq!(fma(-0.992, -0.992, -0.992), -0.00793599999988632,);
221+
assert_eq!(fma(-0.992, -0.992, -0.992), -0.007936000000000007,);
222+
}
223+
224+
#[test]
225+
fn fma_sbb() {
226+
assert_eq!(
227+
fma(-(1.0 - f64::EPSILON), f64::MIN, f64::MIN),
228+
-3991680619069439e277
229+
);
222230
}
223231
}

src/math/pow.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@ mod tests {
604604

605605
// Factoring -1 out:
606606
// (negative anything ^ integer should be (-1 ^ integer) * (positive anything ^ integer))
607-
&[POS_ZERO, NEG_ZERO, POS_ONE, NEG_ONE, POS_EVENS, NEG_EVENS]
607+
(&[POS_ZERO, NEG_ZERO, POS_ONE, NEG_ONE, POS_EVENS, NEG_EVENS])
608608
.iter()
609609
.for_each(|int_set| {
610610
int_set.iter().for_each(|int| {
@@ -616,7 +616,7 @@ mod tests {
616616

617617
// Negative base (imaginary results):
618618
// (-anything except 0 and Infinity ^ non-integer should be NAN)
619-
&NEG[1..(NEG.len() - 1)].iter().for_each(|set| {
619+
(&NEG[1..(NEG.len() - 1)]).iter().for_each(|set| {
620620
set.iter().for_each(|val| {
621621
test_sets(&ALL[3..7], &|v: f64| pow(*val, v), &|_| NAN);
622622
})

0 commit comments

Comments
 (0)