Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FMA implementation producing incorrect results #242

Closed
ajtribick opened this issue Apr 24, 2020 · 1 comment · Fixed by #252
Closed

FMA implementation producing incorrect results #242

ajtribick opened this issue Apr 24, 2020 · 1 comment · Fixed by #252

Comments

@ajtribick
Copy link
Contributor

I've run into an issue with the FMA implementation when investigating creating a no_std version of my double-double arithmetic crate. It breaks the algorithm for multiplying two f64 values to produce a double-double, for which I am using algorithm 3 from Joldes et al. (2017): the high word of the result is the standard floating point multiplication, while the low word uses fused-multiply-add.

The output of the algorithm should be two non-overlapping words, I'm testing this with code similar to the following (uses rand 0.7):

#[cfg(test)]
mod tests {
    use rand::Rng;

    #[test]
    fn fma_test() {
        let mut rng = rand::thread_rng();
        let dist = rand::distributions::Uniform::<f64>::new_inclusive(-10000.0, 10000.0);

        for _ in 0..1000000 {
            let a = rng.sample(dist);
            let b = rng.sample(dist);
            let hi = a * b;
            let lo = libm::fma(a, b, -hi); // 1

            if !hi.is_normal() || !lo.is_normal() { continue; }
            assert!(
                libm::ilogb(hi) - libm::ilogb(lo) >= f64::MANTISSA_DIGITS as i32,
                "fma({:?}, {:?}, {:?})", a, b, -hi
            );
        }
    }
}

The above test fails with libm 0.2.1. If the line marked // 1 is replaced with

            let lo = a.mul_add(b, -hi);

then the test passes.

The equivalent code for f32 using libm::fmaf passes.

I'm not sure if this is the same as #200 but so far I've not seen segfaults.

@jethrogb
Copy link

This may be related to rust-lang/rust#85925 (comment)

jethrogb pushed a commit to jethrogb/libm that referenced this issue Jun 22, 2021
jethrogb pushed a commit to jethrogb/libm that referenced this issue Jun 24, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants