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

FMA implementation producing incorrect results #242

@ajtribick

Description

@ajtribick

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions