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

Functions to distinguish signaling from non-signaling NaN's #51

Closed
cuviper opened this issue Mar 7, 2018 · 6 comments
Closed

Functions to distinguish signaling from non-signaling NaN's #51

cuviper opened this issue Mar 7, 2018 · 6 comments

Comments

@cuviper
Copy link
Member

cuviper commented Mar 7, 2018

From @icefoxen on March 6, 2018 16:14

It'd be nice to be able to distinguish signaling from non-signaling NaN's in some cases. In particular, writing a WebAssembly interpreter; WebAssembly disallows signaling NaN's, so one needs some way to detect and filter them out. Easy to do with bit masks, but it would be nice to be a little more abstract.

Thank you!

Copied from original issue: rust-num/num#364

@cuviper
Copy link
Member Author

cuviper commented Mar 7, 2018

From @icefoxen on March 6, 2018 17:22

If you want 'em, here they are. :-P

/// Returns whether or not the float is a signaling NaN.
/// A signaling NaN has a format like:
/// `s111 1111 1nxx xxxx xxxx xxxx xxxx xxxx`
/// where the `x`'s represent a non-zero number (zero
/// would be infinity) and `n` is 0.
/// The sign bit `s` may be anything.
///
/// On some old-fashioned platforms (PA-RISC, some MIPS)
/// a signaling NaN is marked by `n=1`, but the 2008 revision of
/// IEEE754 defines it to be `n=0`.
pub fn f32_is_signaling_nan(f: f32) -> bool {
    let uf: u32 = f.to_bits();
    let signal_bit = 0b0000_0000_0100_0000_0000_0000_0000_0000;
    let signal_bit = 1 << 22;
    // signaling nan := is NAN and signal bit is clear
    let signal_bit_clear = (uf & signal_bit) == 0;
    f32::is_nan(f) && signal_bit_clear
}

/// Same as `f32_is_signaling_nan()` for `f64`'s.
/// The signaling-nan-bit is bit 51 instead of bit 22
pub fn f64_is_signaling_nan(f: f64) -> bool {
    let uf: u64 = f.to_bits();
    let signal_bit = 1 << 51;
    // signaling nan := is NAN and signal bit is clear
    let signal_bit_clear = (uf & signal_bit) == 0;
    f64::is_nan(f) && signal_bit_clear
}

@cuviper
Copy link
Member Author

cuviper commented Mar 7, 2018

FloatCore or Float::integer_decode can also help safely get the mantissa, if you're on a pre-1.20 Rust without to_bits(). You still have to know where to find that is_quiet bit though.

I'm not sure if there's a good way we can add a method for this without a breaking change. Standalone methods aren't really in the spirit of num-traits. A whole new trait for this would be possible, but seems rather excessive.

@cuviper
Copy link
Member Author

cuviper commented Mar 7, 2018

From @icefoxen on March 7, 2018 14:50

I was imagining it just being a method on the Float trait, really. Not sure if that would count as a breaking change though, since implementors of Float would need to add a method. Honestly maybe this belongs in std instead...

@cuviper
Copy link
Member Author

cuviper commented Mar 7, 2018

Not sure if that would count as a breaking change though, since implementors of Float would need to add a method.

Yes, that makes it breaking, unless we also add a default implementation for that method, but I don't know if that's possible here.

@cuviper
Copy link
Member Author

cuviper commented Mar 7, 2018

From @icefoxen on March 7, 2018 19:33

The obvious default implementation is "return false", but that's not really a correct default implementation, just a stub.

Due to that, and the fact that it is deathly platform-dependent, I think it might fit better in std. Might be something to consider for inclusion in num if/when you want to break the API anyway though.

@cuviper
Copy link
Member Author

cuviper commented Mar 7, 2018

With this moved, I'm also going to close+postpone it, tracked by #47.

@cuviper cuviper closed this as completed Mar 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant