Should NEG_INFINITY * 0.0 return a negative NaN?

I don't have a copy of the IEEE745 standard at hand, and I'm not sure whether it says something about negative infinity multiplication with 0 returning a negative NaN. But rust currently doesn't:

fn main() {
  assert_eq!(1.0f64.copysign(f64::NEG_INFINITY * 0.0), -1.0f64);
}

output:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `1.0`,
 right: `-1.0`', src/main.rs:2:3

(copysign(-f64::NAN) does work)

While C/C++ does:

#include <iostream>
#include <cassert>
#include <cmath>

int main() {
        assert(std::copysign(1.0, -INFINITY * 0.0) == -1.0);
        return 0;
}

output:

Relatedly, printing a negative NaN in C/C++ shows the sign, but not in Rust.

3 Likes

Looks like a problem with const folding, because this passes the assertion(debug build):

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=3d67f9fe513ce0e4743c4ca0786707d6

fn mul_f64(l: f64, r: f64) -> f64 {
    l * r
}

fn main() {
    assert_eq!(1.0f64.copysign(mul_f64(f64::NEG_INFINITY, 0.0)), -1.0f64);
}
2 Likes

Oh indeed! This works too:

use std::ops::Mul;

fn main() {
    assert_eq!(1.0f64.copysign(f64::NEG_INFINITY.mul(0.0)), -1.0f64);
}

Will go file a bug. Edit: filed as NEG_INFINITY * 0.0 is not a negative NaN but NEG_INFINITY.mul(0.0) is · Issue #81261 · rust-lang/rust · GitHub. Thank you.

11 Likes