about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/alloc/src/fmt.rs5
-rw-r--r--library/alloc/tests/fmt.rs3
-rw-r--r--library/core/src/fmt/float.rs19
-rw-r--r--library/core/src/num/dec2flt/mod.rs12
-rw-r--r--library/core/src/num/flt2dec/mod.rs32
-rw-r--r--library/core/tests/num/flt2dec/mod.rs246
-rw-r--r--library/core/tests/num/ieee754.rs158
-rw-r--r--library/core/tests/num/mod.rs1
-rw-r--r--library/std/src/primitive_docs.rs8
-rw-r--r--src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff2
10 files changed, 275 insertions, 211 deletions
diff --git a/library/alloc/src/fmt.rs b/library/alloc/src/fmt.rs
index e765fa9d14c..3ef55f06e51 100644
--- a/library/alloc/src/fmt.rs
+++ b/library/alloc/src/fmt.rs
@@ -161,9 +161,8 @@
 //!
 //! * `+` - This is intended for numeric types and indicates that the sign
 //!         should always be printed. Positive signs are never printed by
-//!         default, and the negative sign is only printed by default for the
-//!         `Signed` trait. This flag indicates that the correct sign (`+` or `-`)
-//!         should always be printed.
+//!         default, and the negative sign is only printed by default for signed values.
+//!         This flag indicates that the correct sign (`+` or `-`) should always be printed.
 //! * `-` - Currently not used
 //! * `#` - This flag indicates that the "alternate" form of printing should
 //!         be used. The alternate forms are:
diff --git a/library/alloc/tests/fmt.rs b/library/alloc/tests/fmt.rs
index a121c54428c..27ab6c07e43 100644
--- a/library/alloc/tests/fmt.rs
+++ b/library/alloc/tests/fmt.rs
@@ -151,8 +151,7 @@ fn test_format_macro_interface() {
     t!(format!("{:+10.3e}", -1.2345e6f64), "  -1.234e6");
 
     // Float edge cases
-    t!(format!("{}", -0.0), "0");
-    t!(format!("{:?}", -0.0), "-0.0");
+    t!(format!("{}", -0.0), "-0");
     t!(format!("{:?}", 0.0), "0.0");
 
     // sign aware zero padding
diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs
index 5908da477e1..ece3cde0015 100644
--- a/library/core/src/fmt/float.rs
+++ b/library/core/src/fmt/float.rs
@@ -54,21 +54,14 @@ where
 }
 
 // Common code of floating point Debug and Display.
-fn float_to_decimal_common<T>(
-    fmt: &mut Formatter<'_>,
-    num: &T,
-    negative_zero: bool,
-    min_precision: usize,
-) -> Result
+fn float_to_decimal_common<T>(fmt: &mut Formatter<'_>, num: &T, min_precision: usize) -> Result
 where
     T: flt2dec::DecodableFloat,
 {
     let force_sign = fmt.sign_plus();
-    let sign = match (force_sign, negative_zero) {
-        (false, false) => flt2dec::Sign::Minus,
-        (false, true) => flt2dec::Sign::MinusRaw,
-        (true, false) => flt2dec::Sign::MinusPlus,
-        (true, true) => flt2dec::Sign::MinusPlusRaw,
+    let sign = match force_sign {
+        false => flt2dec::Sign::Minus,
+        true => flt2dec::Sign::MinusPlus,
     };
 
     if let Some(precision) = fmt.precision {
@@ -156,14 +149,14 @@ macro_rules! floating {
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Debug for $ty {
             fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
-                float_to_decimal_common(fmt, self, true, 1)
+                float_to_decimal_common(fmt, self, 1)
             }
         }
 
         #[stable(feature = "rust1", since = "1.0.0")]
         impl Display for $ty {
             fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
-                float_to_decimal_common(fmt, self, false, 0)
+                float_to_decimal_common(fmt, self, 0)
             }
         }
 
diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs
index 20ac165c6c7..f008a64ffe6 100644
--- a/library/core/src/num/dec2flt/mod.rs
+++ b/library/core/src/num/dec2flt/mod.rs
@@ -239,13 +239,15 @@ fn dec2flt<T: RawFloat>(s: &str) -> Result<T, ParseFloatError> {
         ParseResult::Valid(decimal) => convert(decimal)?,
         ParseResult::ShortcutToInf => T::INFINITY,
         ParseResult::ShortcutToZero => T::ZERO,
-        ParseResult::Invalid => match s {
-            "inf" => T::INFINITY,
-            "NaN" => T::NAN,
-            _ => {
+        ParseResult::Invalid => {
+            if s.eq_ignore_ascii_case("nan") {
+                T::NAN
+            } else if s.eq_ignore_ascii_case("inf") || s.eq_ignore_ascii_case("infinity") {
+                T::INFINITY
+            } else {
                 return Err(pfe_invalid());
             }
-        },
+        }
     };
 
     match sign {
diff --git a/library/core/src/num/flt2dec/mod.rs b/library/core/src/num/flt2dec/mod.rs
index e8f9d6574e2..93bdf5040e0 100644
--- a/library/core/src/num/flt2dec/mod.rs
+++ b/library/core/src/num/flt2dec/mod.rs
@@ -399,14 +399,10 @@ fn digits_to_exp_str<'a>(
 /// Sign formatting options.
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum Sign {
-    /// Prints `-` only for the negative non-zero values.
-    Minus, // -inf -1  0  0  1  inf nan
-    /// Prints `-` only for any negative values (including the negative zero).
-    MinusRaw, // -inf -1 -0  0  1  inf nan
-    /// Prints `-` for the negative non-zero values, or `+` otherwise.
-    MinusPlus, // -inf -1 +0 +0 +1 +inf nan
-    /// Prints `-` for any negative values (including the negative zero), or `+` otherwise.
-    MinusPlusRaw, // -inf -1 -0 +0 +1 +inf nan
+    /// Prints `-` for any negative value.
+    Minus, // -inf -1 -0  0  1  inf nan
+    /// Prints `-` for any negative value, or `+` otherwise.
+    MinusPlus, // -inf -1 -0 +0 +1 +inf nan
 }
 
 /// Returns the static byte string corresponding to the sign to be formatted.
@@ -414,30 +410,14 @@ pub enum Sign {
 fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static str {
     match (*decoded, sign) {
         (FullDecoded::Nan, _) => "",
-        (FullDecoded::Zero, Sign::Minus) => "",
-        (FullDecoded::Zero, Sign::MinusRaw) => {
+        (_, Sign::Minus) => {
             if negative {
                 "-"
             } else {
                 ""
             }
         }
-        (FullDecoded::Zero, Sign::MinusPlus) => "+",
-        (FullDecoded::Zero, Sign::MinusPlusRaw) => {
-            if negative {
-                "-"
-            } else {
-                "+"
-            }
-        }
-        (_, Sign::Minus | Sign::MinusRaw) => {
-            if negative {
-                "-"
-            } else {
-                ""
-            }
-        }
-        (_, Sign::MinusPlus | Sign::MinusPlusRaw) => {
+        (_, Sign::MinusPlus) => {
             if negative {
                 "-"
             } else {
diff --git a/library/core/tests/num/flt2dec/mod.rs b/library/core/tests/num/flt2dec/mod.rs
index 8e95249a79d..960a7ca5ff5 100644
--- a/library/core/tests/num/flt2dec/mod.rs
+++ b/library/core/tests/num/flt2dec/mod.rs
@@ -514,51 +514,38 @@ where
     let f = &mut f_;
 
     assert_eq!(to_string(f, 0.0, Minus, 0), "0");
-    assert_eq!(to_string(f, 0.0, MinusRaw, 0), "0");
+    assert_eq!(to_string(f, 0.0, Minus, 0), "0");
     assert_eq!(to_string(f, 0.0, MinusPlus, 0), "+0");
-    assert_eq!(to_string(f, 0.0, MinusPlusRaw, 0), "+0");
-    assert_eq!(to_string(f, -0.0, Minus, 0), "0");
-    assert_eq!(to_string(f, -0.0, MinusRaw, 0), "-0");
-    assert_eq!(to_string(f, -0.0, MinusPlus, 0), "+0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0), "-0");
+    assert_eq!(to_string(f, -0.0, Minus, 0), "-0");
+    assert_eq!(to_string(f, -0.0, MinusPlus, 0), "-0");
+    assert_eq!(to_string(f, 0.0, Minus, 1), "0.0");
     assert_eq!(to_string(f, 0.0, Minus, 1), "0.0");
-    assert_eq!(to_string(f, 0.0, MinusRaw, 1), "0.0");
     assert_eq!(to_string(f, 0.0, MinusPlus, 1), "+0.0");
-    assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1), "+0.0");
-    assert_eq!(to_string(f, -0.0, Minus, 8), "0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusRaw, 8), "-0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusPlus, 8), "+0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8), "-0.00000000");
+    assert_eq!(to_string(f, -0.0, Minus, 8), "-0.00000000");
+    assert_eq!(to_string(f, -0.0, MinusPlus, 8), "-0.00000000");
 
     assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, 0), "inf");
+    assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf");
     assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 0), "+inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, 0), "+inf");
     assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, 1), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, 64), "NaN");
+    assert_eq!(to_string(f, 0.0 / 0.0, Minus, 1), "NaN");
+    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 64), "NaN");
     assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, 1), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 8), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, 64), "-inf");
+    assert_eq!(to_string(f, -1.0 / 0.0, Minus, 1), "-inf");
+    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64), "-inf");
 
     assert_eq!(to_string(f, 3.14, Minus, 0), "3.14");
-    assert_eq!(to_string(f, 3.14, MinusRaw, 0), "3.14");
+    assert_eq!(to_string(f, 3.14, Minus, 0), "3.14");
     assert_eq!(to_string(f, 3.14, MinusPlus, 0), "+3.14");
-    assert_eq!(to_string(f, 3.14, MinusPlusRaw, 0), "+3.14");
     assert_eq!(to_string(f, -3.14, Minus, 0), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusRaw, 0), "-3.14");
+    assert_eq!(to_string(f, -3.14, Minus, 0), "-3.14");
     assert_eq!(to_string(f, -3.14, MinusPlus, 0), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0), "-3.14");
     assert_eq!(to_string(f, 3.14, Minus, 1), "3.14");
-    assert_eq!(to_string(f, 3.14, MinusRaw, 2), "3.14");
-    assert_eq!(to_string(f, 3.14, MinusPlus, 3), "+3.140");
-    assert_eq!(to_string(f, 3.14, MinusPlusRaw, 4), "+3.1400");
+    assert_eq!(to_string(f, 3.14, Minus, 2), "3.14");
+    assert_eq!(to_string(f, 3.14, MinusPlus, 4), "+3.1400");
+    assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
     assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusRaw, 8), "-3.14000000");
     assert_eq!(to_string(f, -3.14, MinusPlus, 8), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8), "-3.14000000");
 
     assert_eq!(to_string(f, 7.5e-11, Minus, 0), "0.000000000075");
     assert_eq!(to_string(f, 7.5e-11, Minus, 3), "0.000000000075");
@@ -615,68 +602,48 @@ where
     let f = &mut f_;
 
     assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0");
-    assert_eq!(to_string(f, 0.0, MinusRaw, (-4, 16), false), "0");
+    assert_eq!(to_string(f, 0.0, Minus, (-4, 16), false), "0");
     assert_eq!(to_string(f, 0.0, MinusPlus, (-4, 16), false), "+0");
-    assert_eq!(to_string(f, 0.0, MinusPlusRaw, (-4, 16), false), "+0");
-    assert_eq!(to_string(f, -0.0, Minus, (-4, 16), false), "0");
-    assert_eq!(to_string(f, -0.0, MinusRaw, (-4, 16), false), "-0");
-    assert_eq!(to_string(f, -0.0, MinusPlus, (-4, 16), false), "+0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, (-4, 16), false), "-0");
+    assert_eq!(to_string(f, -0.0, Minus, (-4, 16), false), "-0");
+    assert_eq!(to_string(f, -0.0, MinusPlus, (-4, 16), false), "-0");
     assert_eq!(to_string(f, 0.0, Minus, (0, 0), true), "0E0");
-    assert_eq!(to_string(f, 0.0, MinusRaw, (0, 0), false), "0e0");
-    assert_eq!(to_string(f, 0.0, MinusPlus, (-9, -5), true), "+0E0");
-    assert_eq!(to_string(f, 0.0, MinusPlusRaw, (5, 9), false), "+0e0");
-    assert_eq!(to_string(f, -0.0, Minus, (0, 0), true), "0E0");
-    assert_eq!(to_string(f, -0.0, MinusRaw, (0, 0), false), "-0e0");
-    assert_eq!(to_string(f, -0.0, MinusPlus, (-9, -5), true), "+0E0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, (5, 9), false), "-0e0");
+    assert_eq!(to_string(f, 0.0, Minus, (0, 0), false), "0e0");
+    assert_eq!(to_string(f, 0.0, MinusPlus, (5, 9), false), "+0e0");
+    assert_eq!(to_string(f, -0.0, Minus, (0, 0), true), "-0E0");
+    assert_eq!(to_string(f, -0.0, MinusPlus, (5, 9), false), "-0e0");
 
     assert_eq!(to_string(f, 1.0 / 0.0, Minus, (-4, 16), false), "inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, (-4, 16), true), "inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, (-4, 16), false), "+inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, (-4, 16), true), "+inf");
+    assert_eq!(to_string(f, 1.0 / 0.0, Minus, (-4, 16), true), "inf");
+    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, (-4, 16), true), "+inf");
     assert_eq!(to_string(f, 0.0 / 0.0, Minus, (0, 0), false), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, (0, 0), true), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, (-9, -5), false), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, (5, 9), true), "NaN");
+    assert_eq!(to_string(f, 0.0 / 0.0, Minus, (0, 0), true), "NaN");
+    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, (5, 9), true), "NaN");
     assert_eq!(to_string(f, -1.0 / 0.0, Minus, (0, 0), false), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, (0, 0), true), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, (-9, -5), false), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, (5, 9), true), "-inf");
+    assert_eq!(to_string(f, -1.0 / 0.0, Minus, (0, 0), true), "-inf");
+    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, (5, 9), true), "-inf");
 
     assert_eq!(to_string(f, 3.14, Minus, (-4, 16), false), "3.14");
-    assert_eq!(to_string(f, 3.14, MinusRaw, (-4, 16), false), "3.14");
     assert_eq!(to_string(f, 3.14, MinusPlus, (-4, 16), false), "+3.14");
-    assert_eq!(to_string(f, 3.14, MinusPlusRaw, (-4, 16), false), "+3.14");
     assert_eq!(to_string(f, -3.14, Minus, (-4, 16), false), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusRaw, (-4, 16), false), "-3.14");
     assert_eq!(to_string(f, -3.14, MinusPlus, (-4, 16), false), "-3.14");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, (-4, 16), false), "-3.14");
     assert_eq!(to_string(f, 3.14, Minus, (0, 0), true), "3.14E0");
-    assert_eq!(to_string(f, 3.14, MinusRaw, (0, 0), false), "3.14e0");
-    assert_eq!(to_string(f, 3.14, MinusPlus, (-9, -5), true), "+3.14E0");
-    assert_eq!(to_string(f, 3.14, MinusPlusRaw, (5, 9), false), "+3.14e0");
+    assert_eq!(to_string(f, 3.14, Minus, (0, 0), false), "3.14e0");
+    assert_eq!(to_string(f, 3.14, MinusPlus, (5, 9), false), "+3.14e0");
     assert_eq!(to_string(f, -3.14, Minus, (0, 0), true), "-3.14E0");
-    assert_eq!(to_string(f, -3.14, MinusRaw, (0, 0), false), "-3.14e0");
-    assert_eq!(to_string(f, -3.14, MinusPlus, (-9, -5), true), "-3.14E0");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, (5, 9), false), "-3.14e0");
+    assert_eq!(to_string(f, -3.14, Minus, (0, 0), false), "-3.14e0");
+    assert_eq!(to_string(f, -3.14, MinusPlus, (5, 9), false), "-3.14e0");
 
     assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1");
-    assert_eq!(to_string(f, 0.1, MinusRaw, (-4, 16), false), "0.1");
+    assert_eq!(to_string(f, 0.1, Minus, (-4, 16), false), "0.1");
     assert_eq!(to_string(f, 0.1, MinusPlus, (-4, 16), false), "+0.1");
-    assert_eq!(to_string(f, 0.1, MinusPlusRaw, (-4, 16), false), "+0.1");
     assert_eq!(to_string(f, -0.1, Minus, (-4, 16), false), "-0.1");
-    assert_eq!(to_string(f, -0.1, MinusRaw, (-4, 16), false), "-0.1");
     assert_eq!(to_string(f, -0.1, MinusPlus, (-4, 16), false), "-0.1");
-    assert_eq!(to_string(f, -0.1, MinusPlusRaw, (-4, 16), false), "-0.1");
     assert_eq!(to_string(f, 0.1, Minus, (0, 0), true), "1E-1");
-    assert_eq!(to_string(f, 0.1, MinusRaw, (0, 0), false), "1e-1");
-    assert_eq!(to_string(f, 0.1, MinusPlus, (-9, -5), true), "+1E-1");
-    assert_eq!(to_string(f, 0.1, MinusPlusRaw, (5, 9), false), "+1e-1");
+    assert_eq!(to_string(f, 0.1, Minus, (0, 0), false), "1e-1");
+    assert_eq!(to_string(f, 0.1, MinusPlus, (5, 9), false), "+1e-1");
     assert_eq!(to_string(f, -0.1, Minus, (0, 0), true), "-1E-1");
-    assert_eq!(to_string(f, -0.1, MinusRaw, (0, 0), false), "-1e-1");
-    assert_eq!(to_string(f, -0.1, MinusPlus, (-9, -5), true), "-1E-1");
-    assert_eq!(to_string(f, -0.1, MinusPlusRaw, (5, 9), false), "-1e-1");
+    assert_eq!(to_string(f, -0.1, Minus, (0, 0), false), "-1e-1");
+    assert_eq!(to_string(f, -0.1, MinusPlus, (5, 9), false), "-1e-1");
 
     assert_eq!(to_string(f, 7.5e-11, Minus, (-4, 16), false), "7.5e-11");
     assert_eq!(to_string(f, 7.5e-11, Minus, (-11, 10), false), "0.000000000075");
@@ -734,68 +701,51 @@ where
     let f = &mut f_;
 
     assert_eq!(to_string(f, 0.0, Minus, 1, true), "0E0");
-    assert_eq!(to_string(f, 0.0, MinusRaw, 1, false), "0e0");
-    assert_eq!(to_string(f, 0.0, MinusPlus, 1, true), "+0E0");
-    assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1, false), "+0e0");
-    assert_eq!(to_string(f, -0.0, Minus, 1, true), "0E0");
-    assert_eq!(to_string(f, -0.0, MinusRaw, 1, false), "-0e0");
-    assert_eq!(to_string(f, -0.0, MinusPlus, 1, true), "+0E0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 1, false), "-0e0");
+    assert_eq!(to_string(f, 0.0, Minus, 1, false), "0e0");
+    assert_eq!(to_string(f, 0.0, MinusPlus, 1, false), "+0e0");
+    assert_eq!(to_string(f, -0.0, Minus, 1, true), "-0E0");
+    assert_eq!(to_string(f, -0.0, MinusPlus, 1, false), "-0e0");
     assert_eq!(to_string(f, 0.0, Minus, 2, true), "0.0E0");
-    assert_eq!(to_string(f, 0.0, MinusRaw, 2, false), "0.0e0");
-    assert_eq!(to_string(f, 0.0, MinusPlus, 2, true), "+0.0E0");
-    assert_eq!(to_string(f, 0.0, MinusPlusRaw, 2, false), "+0.0e0");
-    assert_eq!(to_string(f, -0.0, Minus, 8, true), "0.0000000E0");
-    assert_eq!(to_string(f, -0.0, MinusRaw, 8, false), "-0.0000000e0");
-    assert_eq!(to_string(f, -0.0, MinusPlus, 8, true), "+0.0000000E0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8, false), "-0.0000000e0");
+    assert_eq!(to_string(f, 0.0, Minus, 2, false), "0.0e0");
+    assert_eq!(to_string(f, 0.0, MinusPlus, 2, false), "+0.0e0");
+    assert_eq!(to_string(f, -0.0, Minus, 8, false), "-0.0000000e0");
+    assert_eq!(to_string(f, -0.0, MinusPlus, 8, false), "-0.0000000e0");
 
     assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1, false), "inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, 1, true), "inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 1, false), "+inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, 1, true), "+inf");
+    assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1, true), "inf");
+    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 1, true), "+inf");
     assert_eq!(to_string(f, 0.0 / 0.0, Minus, 8, false), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, 8, true), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8, false), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, 8, true), "NaN");
+    assert_eq!(to_string(f, 0.0 / 0.0, Minus, 8, true), "NaN");
+    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8, true), "NaN");
     assert_eq!(to_string(f, -1.0 / 0.0, Minus, 64, false), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, 64, true), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64, false), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, 64, true), "-inf");
+    assert_eq!(to_string(f, -1.0 / 0.0, Minus, 64, true), "-inf");
+    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64, true), "-inf");
 
     assert_eq!(to_string(f, 3.14, Minus, 1, true), "3E0");
-    assert_eq!(to_string(f, 3.14, MinusRaw, 1, false), "3e0");
-    assert_eq!(to_string(f, 3.14, MinusPlus, 1, true), "+3E0");
-    assert_eq!(to_string(f, 3.14, MinusPlusRaw, 1, false), "+3e0");
+    assert_eq!(to_string(f, 3.14, Minus, 1, false), "3e0");
+    assert_eq!(to_string(f, 3.14, MinusPlus, 1, false), "+3e0");
     assert_eq!(to_string(f, -3.14, Minus, 2, true), "-3.1E0");
-    assert_eq!(to_string(f, -3.14, MinusRaw, 2, false), "-3.1e0");
-    assert_eq!(to_string(f, -3.14, MinusPlus, 2, true), "-3.1E0");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 2, false), "-3.1e0");
+    assert_eq!(to_string(f, -3.14, Minus, 2, false), "-3.1e0");
+    assert_eq!(to_string(f, -3.14, MinusPlus, 2, false), "-3.1e0");
     assert_eq!(to_string(f, 3.14, Minus, 3, true), "3.14E0");
-    assert_eq!(to_string(f, 3.14, MinusRaw, 3, false), "3.14e0");
-    assert_eq!(to_string(f, 3.14, MinusPlus, 3, true), "+3.14E0");
-    assert_eq!(to_string(f, 3.14, MinusPlusRaw, 3, false), "+3.14e0");
+    assert_eq!(to_string(f, 3.14, Minus, 3, false), "3.14e0");
+    assert_eq!(to_string(f, 3.14, MinusPlus, 3, false), "+3.14e0");
     assert_eq!(to_string(f, -3.14, Minus, 4, true), "-3.140E0");
-    assert_eq!(to_string(f, -3.14, MinusRaw, 4, false), "-3.140e0");
-    assert_eq!(to_string(f, -3.14, MinusPlus, 4, true), "-3.140E0");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 4, false), "-3.140e0");
+    assert_eq!(to_string(f, -3.14, Minus, 4, false), "-3.140e0");
+    assert_eq!(to_string(f, -3.14, MinusPlus, 4, false), "-3.140e0");
 
     assert_eq!(to_string(f, 0.195, Minus, 1, false), "2e-1");
-    assert_eq!(to_string(f, 0.195, MinusRaw, 1, true), "2E-1");
-    assert_eq!(to_string(f, 0.195, MinusPlus, 1, false), "+2e-1");
-    assert_eq!(to_string(f, 0.195, MinusPlusRaw, 1, true), "+2E-1");
+    assert_eq!(to_string(f, 0.195, Minus, 1, true), "2E-1");
+    assert_eq!(to_string(f, 0.195, MinusPlus, 1, true), "+2E-1");
     assert_eq!(to_string(f, -0.195, Minus, 2, false), "-2.0e-1");
-    assert_eq!(to_string(f, -0.195, MinusRaw, 2, true), "-2.0E-1");
-    assert_eq!(to_string(f, -0.195, MinusPlus, 2, false), "-2.0e-1");
-    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 2, true), "-2.0E-1");
+    assert_eq!(to_string(f, -0.195, Minus, 2, true), "-2.0E-1");
+    assert_eq!(to_string(f, -0.195, MinusPlus, 2, true), "-2.0E-1");
     assert_eq!(to_string(f, 0.195, Minus, 3, false), "1.95e-1");
-    assert_eq!(to_string(f, 0.195, MinusRaw, 3, true), "1.95E-1");
-    assert_eq!(to_string(f, 0.195, MinusPlus, 3, false), "+1.95e-1");
-    assert_eq!(to_string(f, 0.195, MinusPlusRaw, 3, true), "+1.95E-1");
+    assert_eq!(to_string(f, 0.195, Minus, 3, true), "1.95E-1");
+    assert_eq!(to_string(f, 0.195, MinusPlus, 3, true), "+1.95E-1");
     assert_eq!(to_string(f, -0.195, Minus, 4, false), "-1.950e-1");
-    assert_eq!(to_string(f, -0.195, MinusRaw, 4, true), "-1.950E-1");
-    assert_eq!(to_string(f, -0.195, MinusPlus, 4, false), "-1.950e-1");
-    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 4, true), "-1.950E-1");
+    assert_eq!(to_string(f, -0.195, Minus, 4, true), "-1.950E-1");
+    assert_eq!(to_string(f, -0.195, MinusPlus, 4, true), "-1.950E-1");
 
     assert_eq!(to_string(f, 9.5, Minus, 1, false), "1e1");
     assert_eq!(to_string(f, 9.5, Minus, 2, false), "9.5e0");
@@ -1007,68 +957,48 @@ where
     let f = &mut f_;
 
     assert_eq!(to_string(f, 0.0, Minus, 0), "0");
-    assert_eq!(to_string(f, 0.0, MinusRaw, 0), "0");
     assert_eq!(to_string(f, 0.0, MinusPlus, 0), "+0");
-    assert_eq!(to_string(f, 0.0, MinusPlusRaw, 0), "+0");
-    assert_eq!(to_string(f, -0.0, Minus, 0), "0");
-    assert_eq!(to_string(f, -0.0, MinusRaw, 0), "-0");
-    assert_eq!(to_string(f, -0.0, MinusPlus, 0), "+0");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 0), "-0");
+    assert_eq!(to_string(f, -0.0, Minus, 0), "-0");
+    assert_eq!(to_string(f, -0.0, MinusPlus, 0), "-0");
     assert_eq!(to_string(f, 0.0, Minus, 1), "0.0");
-    assert_eq!(to_string(f, 0.0, MinusRaw, 1), "0.0");
     assert_eq!(to_string(f, 0.0, MinusPlus, 1), "+0.0");
-    assert_eq!(to_string(f, 0.0, MinusPlusRaw, 1), "+0.0");
-    assert_eq!(to_string(f, -0.0, Minus, 8), "0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusRaw, 8), "-0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusPlus, 8), "+0.00000000");
-    assert_eq!(to_string(f, -0.0, MinusPlusRaw, 8), "-0.00000000");
+    assert_eq!(to_string(f, -0.0, Minus, 8), "-0.00000000");
+    assert_eq!(to_string(f, -0.0, MinusPlus, 8), "-0.00000000");
 
     assert_eq!(to_string(f, 1.0 / 0.0, Minus, 0), "inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusRaw, 1), "inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 8), "+inf");
-    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlusRaw, 64), "+inf");
+    assert_eq!(to_string(f, 1.0 / 0.0, Minus, 1), "inf");
+    assert_eq!(to_string(f, 1.0 / 0.0, MinusPlus, 64), "+inf");
     assert_eq!(to_string(f, 0.0 / 0.0, Minus, 0), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusRaw, 1), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 8), "NaN");
-    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlusRaw, 64), "NaN");
+    assert_eq!(to_string(f, 0.0 / 0.0, Minus, 1), "NaN");
+    assert_eq!(to_string(f, 0.0 / 0.0, MinusPlus, 64), "NaN");
     assert_eq!(to_string(f, -1.0 / 0.0, Minus, 0), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusRaw, 1), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 8), "-inf");
-    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlusRaw, 64), "-inf");
+    assert_eq!(to_string(f, -1.0 / 0.0, Minus, 1), "-inf");
+    assert_eq!(to_string(f, -1.0 / 0.0, MinusPlus, 64), "-inf");
 
     assert_eq!(to_string(f, 3.14, Minus, 0), "3");
-    assert_eq!(to_string(f, 3.14, MinusRaw, 0), "3");
+    assert_eq!(to_string(f, 3.14, Minus, 0), "3");
     assert_eq!(to_string(f, 3.14, MinusPlus, 0), "+3");
-    assert_eq!(to_string(f, 3.14, MinusPlusRaw, 0), "+3");
     assert_eq!(to_string(f, -3.14, Minus, 0), "-3");
-    assert_eq!(to_string(f, -3.14, MinusRaw, 0), "-3");
+    assert_eq!(to_string(f, -3.14, Minus, 0), "-3");
     assert_eq!(to_string(f, -3.14, MinusPlus, 0), "-3");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 0), "-3");
     assert_eq!(to_string(f, 3.14, Minus, 1), "3.1");
-    assert_eq!(to_string(f, 3.14, MinusRaw, 2), "3.14");
-    assert_eq!(to_string(f, 3.14, MinusPlus, 3), "+3.140");
-    assert_eq!(to_string(f, 3.14, MinusPlusRaw, 4), "+3.1400");
+    assert_eq!(to_string(f, 3.14, Minus, 2), "3.14");
+    assert_eq!(to_string(f, 3.14, MinusPlus, 4), "+3.1400");
+    assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
     assert_eq!(to_string(f, -3.14, Minus, 8), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusRaw, 8), "-3.14000000");
     assert_eq!(to_string(f, -3.14, MinusPlus, 8), "-3.14000000");
-    assert_eq!(to_string(f, -3.14, MinusPlusRaw, 8), "-3.14000000");
 
     assert_eq!(to_string(f, 0.195, Minus, 0), "0");
-    assert_eq!(to_string(f, 0.195, MinusRaw, 0), "0");
     assert_eq!(to_string(f, 0.195, MinusPlus, 0), "+0");
-    assert_eq!(to_string(f, 0.195, MinusPlusRaw, 0), "+0");
     assert_eq!(to_string(f, -0.195, Minus, 0), "-0");
-    assert_eq!(to_string(f, -0.195, MinusRaw, 0), "-0");
+    assert_eq!(to_string(f, -0.195, Minus, 0), "-0");
     assert_eq!(to_string(f, -0.195, MinusPlus, 0), "-0");
-    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 0), "-0");
     assert_eq!(to_string(f, 0.195, Minus, 1), "0.2");
-    assert_eq!(to_string(f, 0.195, MinusRaw, 2), "0.20");
-    assert_eq!(to_string(f, 0.195, MinusPlus, 3), "+0.195");
-    assert_eq!(to_string(f, 0.195, MinusPlusRaw, 4), "+0.1950");
+    assert_eq!(to_string(f, 0.195, Minus, 2), "0.20");
+    assert_eq!(to_string(f, 0.195, MinusPlus, 4), "+0.1950");
     assert_eq!(to_string(f, -0.195, Minus, 5), "-0.19500");
-    assert_eq!(to_string(f, -0.195, MinusRaw, 6), "-0.195000");
-    assert_eq!(to_string(f, -0.195, MinusPlus, 7), "-0.1950000");
-    assert_eq!(to_string(f, -0.195, MinusPlusRaw, 8), "-0.19500000");
+    assert_eq!(to_string(f, -0.195, Minus, 6), "-0.195000");
+    assert_eq!(to_string(f, -0.195, MinusPlus, 8), "-0.19500000");
 
     assert_eq!(to_string(f, 999.5, Minus, 0), "1000");
     assert_eq!(to_string(f, 999.5, Minus, 1), "999.5");
diff --git a/library/core/tests/num/ieee754.rs b/library/core/tests/num/ieee754.rs
new file mode 100644
index 00000000000..f6e5dfc98c7
--- /dev/null
+++ b/library/core/tests/num/ieee754.rs
@@ -0,0 +1,158 @@
+//! IEEE 754 floating point compliance tests
+//!
+//! To understand IEEE 754's requirements on a programming language, one must understand that the
+//! requirements of IEEE 754 rest on the total programming environment, and not entirely on any
+//! one component. That means the hardware, language, and even libraries are considered part of
+//! conforming floating point support in a programming environment.
+//!
+//! A programming language's duty, accordingly, is:
+//!   1. offer access to the hardware where the hardware offers support
+//!   2. provide operations that fulfill the remaining requirements of the standard
+//!   3. provide the ability to write additional software that can fulfill those requirements
+//!
+//! This may be fulfilled in any combination that the language sees fit. However, to claim that
+//! a language supports IEEE 754 is to suggest that it has fulfilled requirements 1 and 2, without
+//! deferring minimum requirements to libraries. This is because support for IEEE 754 is defined
+//! as complete support for at least one specified floating point type as an "arithmetic" and
+//! "interchange" format, plus specified type conversions to "external character sequences" and
+//! integer types.
+//!
+//! For our purposes,
+//! "interchange format"          => f32, f64
+//! "arithmetic format"           => f32, f64, and any "soft floats"
+//! "external character sequence" => str from any float
+//! "integer format"              => {i,u}{8,16,32,64,128}
+//!
+//! None of these tests are against Rust's own implementation. They are only tests against the
+//! standard. That is why they accept wildly diverse inputs or may seem to duplicate other tests.
+//! Please consider this carefully when adding, removing, or reorganizing these tests. They are
+//! here so that it is clear what tests are required by the standard and what can be changed.
+use ::core::str::FromStr;
+
+// IEEE 754 for many tests is applied to specific bit patterns.
+// These generally are not applicable to NaN, however.
+macro_rules! assert_biteq {
+    ($lhs:expr, $rhs:expr) => {
+        assert_eq!($lhs.to_bits(), $rhs.to_bits())
+    };
+}
+
+// ToString uses the default fmt::Display impl without special concerns, and bypasses other parts
+// of the formatting infrastructure, which makes it ideal for testing here.
+#[allow(unused_macros)]
+macro_rules! roundtrip {
+    ($f:expr => $t:ty) => {
+        ($f).to_string().parse::<$t>().unwrap()
+    };
+}
+
+macro_rules! assert_floats_roundtrip {
+    ($f:ident) => {
+        assert_biteq!(f32::$f, roundtrip!(f32::$f => f32));
+        assert_biteq!(f64::$f, roundtrip!(f64::$f => f64));
+    };
+    ($f:expr) => {
+        assert_biteq!($f as f32, roundtrip!($f => f32));
+        assert_biteq!($f as f64, roundtrip!($f => f64));
+    }
+}
+
+macro_rules! assert_floats_bitne {
+    ($lhs:ident, $rhs:ident) => {
+        assert_ne!(f32::$lhs.to_bits(), f32::$rhs.to_bits());
+        assert_ne!(f64::$lhs.to_bits(), f64::$rhs.to_bits());
+    };
+    ($lhs:expr, $rhs:expr) => {
+        assert_ne!(f32::to_bits($lhs), f32::to_bits($rhs));
+        assert_ne!(f64::to_bits($lhs), f64::to_bits($rhs));
+    };
+}
+
+// We must preserve signs on all numbers. That includes zero.
+// -0 and 0 are == normally, so test bit equality.
+#[test]
+fn preserve_signed_zero() {
+    assert_floats_roundtrip!(-0.0);
+    assert_floats_roundtrip!(0.0);
+    assert_floats_bitne!(0.0, -0.0);
+}
+
+#[test]
+fn preserve_signed_infinity() {
+    assert_floats_roundtrip!(INFINITY);
+    assert_floats_roundtrip!(NEG_INFINITY);
+    assert_floats_bitne!(INFINITY, NEG_INFINITY);
+}
+
+#[test]
+fn infinity_to_str() {
+    assert!(match f32::INFINITY.to_string().to_lowercase().as_str() {
+        "+infinity" | "infinity" => true,
+        "+inf" | "inf" => true,
+        _ => false,
+    });
+    assert!(
+        match f64::INFINITY.to_string().to_lowercase().as_str() {
+            "+infinity" | "infinity" => true,
+            "+inf" | "inf" => true,
+            _ => false,
+        },
+        "Infinity must write to a string as some casing of inf or infinity, with an optional +."
+    );
+}
+
+#[test]
+fn neg_infinity_to_str() {
+    assert!(match f32::NEG_INFINITY.to_string().to_lowercase().as_str() {
+        "-infinity" | "-inf" => true,
+        _ => false,
+    });
+    assert!(
+        match f64::NEG_INFINITY.to_string().to_lowercase().as_str() {
+            "-infinity" | "-inf" => true,
+            _ => false,
+        },
+        "Negative Infinity must write to a string as some casing of -inf or -infinity"
+    )
+}
+
+#[test]
+fn nan_to_str() {
+    assert!(
+        match f32::NAN.to_string().to_lowercase().as_str() {
+            "nan" | "+nan" | "-nan" => true,
+            _ => false,
+        },
+        "NaNs must write to a string as some casing of nan."
+    )
+}
+
+// "+"?("inf"|"infinity") in any case => Infinity
+#[test]
+fn infinity_from_str() {
+    assert_biteq!(f32::INFINITY, f32::from_str("infinity").unwrap());
+    assert_biteq!(f32::INFINITY, f32::from_str("inf").unwrap());
+    assert_biteq!(f32::INFINITY, f32::from_str("+infinity").unwrap());
+    assert_biteq!(f32::INFINITY, f32::from_str("+inf").unwrap());
+    // yes! this means you are weLcOmE tO mY iNfInItElY tWiStEd MiNd
+    assert_biteq!(f32::INFINITY, f32::from_str("+iNfInItY").unwrap());
+}
+
+// "-inf"|"-infinity" in any case => Negative Infinity
+#[test]
+fn neg_infinity_from_str() {
+    assert_biteq!(f32::NEG_INFINITY, f32::from_str("-infinity").unwrap());
+    assert_biteq!(f32::NEG_INFINITY, f32::from_str("-inf").unwrap());
+    assert_biteq!(f32::NEG_INFINITY, f32::from_str("-INF").unwrap());
+    assert_biteq!(f32::NEG_INFINITY, f32::from_str("-INFinity").unwrap());
+}
+
+// ("+"|"-"")?"s"?"nan" in any case => qNaN
+#[test]
+fn qnan_from_str() {
+    assert!("nan".parse::<f32>().unwrap().is_nan());
+    assert!("-nan".parse::<f32>().unwrap().is_nan());
+    assert!("+nan".parse::<f32>().unwrap().is_nan());
+    assert!("+NAN".parse::<f32>().unwrap().is_nan());
+    assert!("-NaN".parse::<f32>().unwrap().is_nan());
+}
diff --git a/library/core/tests/num/mod.rs b/library/core/tests/num/mod.rs
index e66a73ac128..bbb67667dfc 100644
--- a/library/core/tests/num/mod.rs
+++ b/library/core/tests/num/mod.rs
@@ -32,6 +32,7 @@ mod flt2dec;
 mod ops;
 mod wrapping;
 
+mod ieee754;
 mod nan;
 
 /// Adds the attribute to all items in the block.
diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs
index d4bb2083d00..64b22b64f4b 100644
--- a/library/std/src/primitive_docs.rs
+++ b/library/std/src/primitive_docs.rs
@@ -805,10 +805,12 @@ mod prim_tuple {}
 /// often discard insignificant digits: `println!("{}", 1.0f32 / 5.0f32)` will
 /// print `0.2`.
 ///
-/// Additionally, `f32` can represent a couple of special values:
+/// Additionally, `f32` can represent some special values:
 ///
-/// - `-0`: this is just due to how floats are encoded. It is semantically
-///   equivalent to `0` and `-0.0 == 0.0` results in `true`.
+/// - -0.0: IEEE 754 floating point numbers have a bit that indicates their sign, so -0.0 is a
+///   possible value. For comparison `-0.0 == +0.0` is true but floating point operations can
+///   carry the sign bit through arithmetic operations. This means `-1.0 * 0.0` produces -0.0 and
+///   a negative number rounded to a value smaller than a float can represent also produces -0.0.
 /// - [∞](#associatedconstant.INFINITY) and
 ///   [−∞](#associatedconstant.NEG_INFINITY): these result from calculations
 ///   like `1.0 / 0.0`.
diff --git a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
index caa02abf019..3a50ed224b5 100644
--- a/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
+++ b/src/test/mir-opt/funky_arms.float_to_exponential_common.ConstProp.diff
@@ -51,7 +51,7 @@
       }
   
       bb2: {
-          discriminant(_6) = 2;            // scope 1 at $DIR/funky_arms.rs:21:17: 21:41
+          discriminant(_6) = 1;            // scope 1 at $DIR/funky_arms.rs:21:17: 21:41
           goto -> bb4;                     // scope 1 at $DIR/funky_arms.rs:19:16: 22:6
       }