mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
support: Print sNaN or qNaN for hex floats
Give more descriptive output in tests since we sometimes need to treat these differently. We still don't parse `sNaN`/`qNaN` for now, though we could in the future.
This commit is contained in:
@@ -340,8 +340,10 @@ pub(super) fn fmt_any_hex<F: Float>(x: &F, f: &mut fmt::Formatter<'_>) -> fmt::R
|
||||
write!(f, "-")?;
|
||||
}
|
||||
|
||||
if x.is_nan() {
|
||||
return write!(f, "NaN");
|
||||
if x.is_snan() {
|
||||
return write!(f, "sNaN");
|
||||
} else if x.is_nan() {
|
||||
return write!(f, "qNaN");
|
||||
} else if x.is_infinite() {
|
||||
return write!(f, "inf");
|
||||
} else if *x == F::ZERO {
|
||||
@@ -511,6 +513,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
#[cfg(test)]
|
||||
mod parse_tests {
|
||||
extern crate std;
|
||||
use std::string::String;
|
||||
use std::{format, println};
|
||||
|
||||
use super::*;
|
||||
@@ -559,6 +562,16 @@ fn rounding_properties(s: &str) -> Result<(), HexFloatParseError> {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(not(f16_enabled), expect(unused))]
|
||||
pub fn canonicalize_snan_str(s: String) -> String {
|
||||
if s.contains("sNaN") || s.contains("qNaN") {
|
||||
s.replace("sNaN", "NaN").replace("qNaN", "NaN")
|
||||
} else {
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(f16_enabled)]
|
||||
fn test_rounding() {
|
||||
@@ -566,7 +579,11 @@ fn test_rounding() {
|
||||
for i in -n..n {
|
||||
let u = i.rotate_right(11) as u32;
|
||||
let s = format!("{}", Hexf(f32::from_bits(u)));
|
||||
assert!(rounding_properties(&s).is_ok());
|
||||
let s = canonicalize_snan_str(s);
|
||||
match rounding_properties(&s) {
|
||||
Ok(()) => (),
|
||||
Err(e) => panic!("failed rounding properties for `{s}`: {e:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1099,8 +1116,11 @@ fn test_f16() {
|
||||
use std::format;
|
||||
// Exhaustively check that `f16` roundtrips.
|
||||
for x in 0..=u16::MAX {
|
||||
use super::parse_tests::canonicalize_snan_str;
|
||||
|
||||
let f = f16::from_bits(x);
|
||||
let s = format!("{}", Hexf(f));
|
||||
let s = canonicalize_snan_str(s);
|
||||
let from_s = hf16(&s);
|
||||
|
||||
if f.is_nan() && from_s.is_nan() {
|
||||
@@ -1119,6 +1139,8 @@ fn test_f16() {
|
||||
#[cfg(f16_enabled)]
|
||||
fn test_f16_to_f32() {
|
||||
use std::format;
|
||||
|
||||
use super::parse_tests::canonicalize_snan_str;
|
||||
// Exhaustively check that these are equivalent for all `f16`:
|
||||
// - `f16 -> f32`
|
||||
// - `f16 -> str -> f32`
|
||||
@@ -1127,8 +1149,10 @@ fn test_f16_to_f32() {
|
||||
for x in 0..=u16::MAX {
|
||||
let f16 = f16::from_bits(x);
|
||||
let s16 = format!("{}", Hexf(f16));
|
||||
let s16 = canonicalize_snan_str(s16);
|
||||
let f32 = f16 as f32;
|
||||
let s32 = format!("{}", Hexf(f32));
|
||||
let s32 = canonicalize_snan_str(s32);
|
||||
|
||||
let a = hf32(&s16);
|
||||
let b = hf32(&s32);
|
||||
@@ -1169,8 +1193,17 @@ fn spot_checks() {
|
||||
assert_eq!(Hexf(f32::NEG_ZERO).to_string(), "-0x0p+0");
|
||||
assert_eq!(Hexf(f64::NEG_ZERO).to_string(), "-0x0p+0");
|
||||
|
||||
assert_eq!(Hexf(f32::NAN).to_string(), "NaN");
|
||||
assert_eq!(Hexf(f64::NAN).to_string(), "NaN");
|
||||
assert_eq!(Hexf(f32::NAN).to_string(), "qNaN");
|
||||
assert_eq!(Hexf(f64::NAN).to_string(), "qNaN");
|
||||
assert_eq!(Hexf(f32::NEG_NAN).to_string(), "-qNaN");
|
||||
assert_eq!(Hexf(f64::NEG_NAN).to_string(), "-qNaN");
|
||||
if !cfg!(x86_no_sse) {
|
||||
// FIXME(rust-lang/rust#115567): calls quiet the sNaN
|
||||
assert_eq!(Hexf(f32::SNAN).to_string(), "sNaN");
|
||||
assert_eq!(Hexf(f64::SNAN).to_string(), "sNaN");
|
||||
assert_eq!(Hexf(f32::NEG_SNAN).to_string(), "-sNaN");
|
||||
assert_eq!(Hexf(f64::NEG_SNAN).to_string(), "-sNaN");
|
||||
}
|
||||
|
||||
assert_eq!(Hexf(f32::INFINITY).to_string(), "inf");
|
||||
assert_eq!(Hexf(f64::INFINITY).to_string(), "inf");
|
||||
@@ -1184,7 +1217,9 @@ fn spot_checks() {
|
||||
assert_eq!(Hexf(f16::MIN).to_string(), "-0x1.ffcp+15");
|
||||
assert_eq!(Hexf(f16::ZERO).to_string(), "0x0p+0");
|
||||
assert_eq!(Hexf(f16::NEG_ZERO).to_string(), "-0x0p+0");
|
||||
assert_eq!(Hexf(f16::NAN).to_string(), "NaN");
|
||||
assert_eq!(Hexf(f16::NAN).to_string(), "qNaN");
|
||||
assert_eq!(Hexf(f16::SNAN).to_string(), "sNaN");
|
||||
assert_eq!(Hexf(f16::NEG_NAN).to_string(), "-qNaN");
|
||||
assert_eq!(Hexf(f16::INFINITY).to_string(), "inf");
|
||||
assert_eq!(Hexf(f16::NEG_INFINITY).to_string(), "-inf");
|
||||
}
|
||||
@@ -1201,7 +1236,9 @@ fn spot_checks() {
|
||||
);
|
||||
assert_eq!(Hexf(f128::ZERO).to_string(), "0x0p+0");
|
||||
assert_eq!(Hexf(f128::NEG_ZERO).to_string(), "-0x0p+0");
|
||||
assert_eq!(Hexf(f128::NAN).to_string(), "NaN");
|
||||
assert_eq!(Hexf(f128::NAN).to_string(), "qNaN");
|
||||
assert_eq!(Hexf(f128::SNAN).to_string(), "sNaN");
|
||||
assert_eq!(Hexf(f128::NEG_NAN).to_string(), "-qNaN");
|
||||
assert_eq!(Hexf(f128::INFINITY).to_string(), "inf");
|
||||
assert_eq!(Hexf(f128::NEG_INFINITY).to_string(), "-inf");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user