diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 17ca854768546..74d337f1dc05f 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -418,6 +418,15 @@ impl f32 { pub const MAX_10_EXP: i32 = 38; /// Not a Number (NaN). + /// + /// Note that IEEE-745 doesn't define just a single NaN value; + /// a plethora of bit patterns are considered to be NaN. + /// Furthermore, the standard makes a difference + /// between a "signaling" and a "quiet" NaN, + /// and allows inspecting its "payload" (the unspecified bits in the bit pattern). + /// This constant isn't guaranteed to equal to any specific NaN bitpattern, + /// and the stability of its representation over Rust versions + /// and target platforms isn't guaranteed. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const NAN: f32 = 0.0_f32 / 0.0_f32; /// Infinity (∞). @@ -427,7 +436,7 @@ impl f32 { #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const NEG_INFINITY: f32 = -1.0_f32 / 0.0_f32; - /// Returns `true` if this value is `NaN`. + /// Returns `true` if this value is NaN. /// /// ``` /// let nan = f32::NAN; @@ -476,7 +485,7 @@ impl f32 { self.abs_private() == Self::INFINITY } - /// Returns `true` if this number is neither infinite nor `NaN`. + /// Returns `true` if this number is neither infinite nor NaN. /// /// ``` /// let f = 7.0f32; @@ -527,7 +536,7 @@ impl f32 { } /// Returns `true` if the number is neither zero, infinite, - /// [subnormal], or `NaN`. + /// [subnormal], or NaN. /// /// ``` /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32 @@ -582,8 +591,12 @@ impl f32 { } } - /// Returns `true` if `self` has a positive sign, including `+0.0`, `NaN`s with - /// positive sign bit and positive infinity. + /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with + /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any + /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that + /// the bit pattern of NaNs are conserved over arithmetic operations, the result of + /// `is_sign_positive` on a NaN might produce an unexpected result in some cases. + /// See [explanation of NaN as a special value](f32) for more info. /// /// ``` /// let f = 7.0_f32; @@ -600,8 +613,12 @@ impl f32 { !self.is_sign_negative() } - /// Returns `true` if `self` has a negative sign, including `-0.0`, `NaN`s with - /// negative sign bit and negative infinity. + /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with + /// negative sign bit and negative infinity. Note that IEEE-745 doesn't assign any + /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that + /// the bit pattern of NaNs are conserved over arithmetic operations, the result of + /// `is_sign_negative` on a NaN might produce an unexpected result in some cases. + /// See [explanation of NaN as a special value](f32) for more info. /// /// ``` /// let f = 7.0f32; @@ -672,10 +689,12 @@ impl f32 { self * (value / 180.0f32) } - /// Returns the maximum of the two numbers. + /// Returns the maximum of the two numbers, ignoring NaN. /// - /// Follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs. - /// This matches the behavior of libm’s fmax. + /// If one of the arguments is NaN, then the other argument is returned. + /// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs; + /// this function handles all NaNs the same way and avoids maxNum's problems with associativity. + /// This also matches the behavior of libm’s fmax. /// /// ``` /// let x = 1.0f32; @@ -683,8 +702,6 @@ impl f32 { /// /// assert_eq!(x.max(y), y); /// ``` - /// - /// If one of the arguments is NaN, then the other argument is returned. #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -692,10 +709,12 @@ impl f32 { intrinsics::maxnumf32(self, other) } - /// Returns the minimum of the two numbers. + /// Returns the minimum of the two numbers, ignoring NaN. /// - /// Follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs. - /// This matches the behavior of libm’s fmin. + /// If one of the arguments is NaN, then the other argument is returned. + /// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs; + /// this function handles all NaNs the same way and avoids minNum's problems with associativity. + /// This also matches the behavior of libm’s fmin. /// /// ``` /// let x = 1.0f32; @@ -703,8 +722,6 @@ impl f32 { /// /// assert_eq!(x.min(y), x); /// ``` - /// - /// If one of the arguments is NaN, then the other argument is returned. #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -712,7 +729,7 @@ impl f32 { intrinsics::minnumf32(self, other) } - /// Returns the maximum of the two numbers, propagating NaNs. + /// Returns the maximum of the two numbers, propagating NaN. /// /// This returns NaN when *either* argument is NaN, as opposed to /// [`f32::max`] which only returns NaN when *both* arguments are NaN. @@ -729,6 +746,9 @@ impl f32 { /// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater /// of the two numbers. For this operation, -0.0 is considered to be less than +0.0. /// Note that this follows the semantics specified in IEEE 754-2019. + /// + /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN + /// operand is conserved; see [explanation of NaN as a special value](f32) for more info. #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] @@ -744,7 +764,7 @@ impl f32 { } } - /// Returns the minimum of the two numbers, propagating NaNs. + /// Returns the minimum of the two numbers, propagating NaN. /// /// This returns NaN when *either* argument is NaN, as opposed to /// [`f32::min`] which only returns NaN when *both* arguments are NaN. @@ -761,6 +781,9 @@ impl f32 { /// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser /// of the two numbers. For this operation, -0.0 is considered to be less than +0.0. /// Note that this follows the semantics specified in IEEE 754-2019. + /// + /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN + /// operand is conserved; see [explanation of NaN as a special value](f32) for more info. #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] @@ -885,6 +908,9 @@ impl f32 { /// Return the memory representation of this floating point number as a byte array in /// big-endian (network) byte order. /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -903,6 +929,9 @@ impl f32 { /// Return the memory representation of this floating point number as a byte array in /// little-endian byte order. /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -927,6 +956,9 @@ impl f32 { /// [`to_be_bytes`]: f32::to_be_bytes /// [`to_le_bytes`]: f32::to_le_bytes /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -951,6 +983,9 @@ impl f32 { /// Create a floating point value from its representation as a byte array in big endian. /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -967,6 +1002,9 @@ impl f32 { /// Create a floating point value from its representation as a byte array in little endian. /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -990,6 +1028,9 @@ impl f32 { /// [`from_be_bytes`]: f32::from_be_bytes /// [`from_le_bytes`]: f32::from_le_bytes /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 350d8529de57a..c8ce6f0e3a82d 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -417,6 +417,15 @@ impl f64 { pub const MAX_10_EXP: i32 = 308; /// Not a Number (NaN). + /// + /// Note that IEEE-745 doesn't define just a single NaN value; + /// a plethora of bit patterns are considered to be NaN. + /// Furthermore, the standard makes a difference + /// between a "signaling" and a "quiet" NaN, + /// and allows inspecting its "payload" (the unspecified bits in the bit pattern). + /// This constant isn't guaranteed to equal to any specific NaN bitpattern, + /// and the stability of its representation over Rust versions + /// and target platforms isn't guaranteed. #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const NAN: f64 = 0.0_f64 / 0.0_f64; /// Infinity (∞). @@ -426,7 +435,7 @@ impl f64 { #[stable(feature = "assoc_int_consts", since = "1.43.0")] pub const NEG_INFINITY: f64 = -1.0_f64 / 0.0_f64; - /// Returns `true` if this value is `NaN`. + /// Returns `true` if this value is NaN. /// /// ``` /// let nan = f64::NAN; @@ -475,7 +484,7 @@ impl f64 { self.abs_private() == Self::INFINITY } - /// Returns `true` if this number is neither infinite nor `NaN`. + /// Returns `true` if this number is neither infinite nor NaN. /// /// ``` /// let f = 7.0f64; @@ -526,7 +535,7 @@ impl f64 { } /// Returns `true` if the number is neither zero, infinite, - /// [subnormal], or `NaN`. + /// [subnormal], or NaN. /// /// ``` /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308f64 @@ -581,8 +590,12 @@ impl f64 { } } - /// Returns `true` if `self` has a positive sign, including `+0.0`, `NaN`s with - /// positive sign bit and positive infinity. + /// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with + /// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any + /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that + /// the bit pattern of NaNs are conserved over arithmetic operations, the result of + /// `is_sign_positive` on a NaN might produce an unexpected result in some cases. + /// See [explanation of NaN as a special value](f32) for more info. /// /// ``` /// let f = 7.0_f64; @@ -608,8 +621,12 @@ impl f64 { self.is_sign_positive() } - /// Returns `true` if `self` has a negative sign, including `-0.0`, `NaN`s with - /// negative sign bit and negative infinity. + /// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with + /// negative sign bit and negative infinity. Note that IEEE-745 doesn't assign any + /// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that + /// the bit pattern of NaNs are conserved over arithmetic operations, the result of + /// `is_sign_negative` on a NaN might produce an unexpected result in some cases. + /// See [explanation of NaN as a special value](f32) for more info. /// /// ``` /// let f = 7.0_f64; @@ -688,10 +705,12 @@ impl f64 { self * (value / 180.0) } - /// Returns the maximum of the two numbers. + /// Returns the maximum of the two numbers, ignoring NaN. /// - /// Follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs. - /// This matches the behavior of libm’s fmax. + /// If one of the arguments is NaN, then the other argument is returned. + /// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs; + /// this function handles all NaNs the same way and avoids maxNum's problems with associativity. + /// This also matches the behavior of libm’s fmax. /// /// ``` /// let x = 1.0_f64; @@ -699,8 +718,6 @@ impl f64 { /// /// assert_eq!(x.max(y), y); /// ``` - /// - /// If one of the arguments is NaN, then the other argument is returned. #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -708,10 +725,12 @@ impl f64 { intrinsics::maxnumf64(self, other) } - /// Returns the minimum of the two numbers. + /// Returns the minimum of the two numbers, ignoring NaN. /// - /// Follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs. - /// This matches the behavior of libm’s fmin. + /// If one of the arguments is NaN, then the other argument is returned. + /// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs; + /// this function handles all NaNs the same way and avoids minNum's problems with associativity. + /// This also matches the behavior of libm’s fmin. /// /// ``` /// let x = 1.0_f64; @@ -719,8 +738,6 @@ impl f64 { /// /// assert_eq!(x.min(y), x); /// ``` - /// - /// If one of the arguments is NaN, then the other argument is returned. #[must_use = "this returns the result of the comparison, without modifying either input"] #[stable(feature = "rust1", since = "1.0.0")] #[inline] @@ -728,7 +745,7 @@ impl f64 { intrinsics::minnumf64(self, other) } - /// Returns the maximum of the two numbers, propagating NaNs. + /// Returns the maximum of the two numbers, propagating NaN. /// /// This returns NaN when *either* argument is NaN, as opposed to /// [`f64::max`] which only returns NaN when *both* arguments are NaN. @@ -745,6 +762,9 @@ impl f64 { /// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater /// of the two numbers. For this operation, -0.0 is considered to be less than +0.0. /// Note that this follows the semantics specified in IEEE 754-2019. + /// + /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN + /// operand is conserved; see [explanation of NaN as a special value](f32) for more info. #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] @@ -760,7 +780,7 @@ impl f64 { } } - /// Returns the minimum of the two numbers, propagating NaNs. + /// Returns the minimum of the two numbers, propagating NaN. /// /// This returns NaN when *either* argument is NaN, as opposed to /// [`f64::min`] which only returns NaN when *both* arguments are NaN. @@ -777,6 +797,9 @@ impl f64 { /// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser /// of the two numbers. For this operation, -0.0 is considered to be less than +0.0. /// Note that this follows the semantics specified in IEEE 754-2019. + /// + /// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN + /// operand is conserved; see [explanation of NaN as a special value](f32) for more info. #[must_use = "this returns the result of the comparison, without modifying either input"] #[unstable(feature = "float_minimum_maximum", issue = "91079")] #[inline] @@ -901,6 +924,9 @@ impl f64 { /// Return the memory representation of this floating point number as a byte array in /// big-endian (network) byte order. /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -919,6 +945,9 @@ impl f64 { /// Return the memory representation of this floating point number as a byte array in /// little-endian byte order. /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -943,6 +972,9 @@ impl f64 { /// [`to_be_bytes`]: f64::to_be_bytes /// [`to_le_bytes`]: f64::to_le_bytes /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -967,6 +999,9 @@ impl f64 { /// Create a floating point value from its representation as a byte array in big endian. /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -983,6 +1018,9 @@ impl f64 { /// Create a floating point value from its representation as a byte array in little endian. /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` @@ -1006,6 +1044,9 @@ impl f64 { /// [`from_be_bytes`]: f64::from_be_bytes /// [`from_le_bytes`]: f64::from_le_bytes /// + /// See [`from_bits`](Self::from_bits) for some discussion of the + /// portability of this operation (there are almost no issues). + /// /// # Examples /// /// ``` diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index 225a679efd221..ac4e668112b94 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -977,10 +977,22 @@ mod prim_tuple {} /// like `1.0 / 0.0`. /// - [NaN (not a number)](#associatedconstant.NAN): this value results from /// calculations like `(-1.0).sqrt()`. NaN has some potentially unexpected -/// behavior: it is unequal to any float, including itself! It is also neither -/// smaller nor greater than any float, making it impossible to sort. Lastly, -/// it is considered infectious as almost all calculations where one of the -/// operands is NaN will also result in NaN. +/// behavior: +/// - It is unequal to any float, including itself! This is the reason `f32` +/// doesn't implement the `Eq` trait. +/// - It is also neither smaller nor greater than any float, making it +/// impossible to sort by the default comparison operation, which is the +/// reason `f32` doesn't implement the `Ord` trait. +/// - It is also considered *infectious* as almost all calculations where one +/// of the operands is NaN will also result in NaN. The explanations on this +/// page only explicitly document behavior on NaN operands if this default +/// is deviated from. +/// - Lastly, there are multiple bit patterns that are considered NaN. +/// Rust does not currently guarantee that the bit patterns of NaN are +/// preserved over arithmetic operations, and they are not guaranteed to be +/// portable or even fully deterministic! This means that there may be some +/// surprising results upon inspecting the bit patterns, +/// as the same calculations might produce NaNs with different bit patterns. /// /// For more information on floating point numbers, see [Wikipedia][wikipedia]. /// diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 70b5941c7c72b..4cf234a527d56 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -30,7 +30,7 @@ pub use core::f32::{ #[cfg(not(test))] #[cfg_attr(bootstrap, lang = "f32_runtime")] impl f32 { - /// Returns the largest integer less than or equal to a number. + /// Returns the largest integer less than or equal to `self`. /// /// # Examples /// @@ -51,7 +51,7 @@ impl f32 { unsafe { intrinsics::floorf32(self) } } - /// Returns the smallest integer greater than or equal to a number. + /// Returns the smallest integer greater than or equal to `self`. /// /// # Examples /// @@ -70,7 +70,7 @@ impl f32 { unsafe { intrinsics::ceilf32(self) } } - /// Returns the nearest integer to a number. Round half-way cases away from + /// Returns the nearest integer to `self`. Round half-way cases away from /// `0.0`. /// /// # Examples @@ -90,7 +90,8 @@ impl f32 { unsafe { intrinsics::roundf32(self) } } - /// Returns the integer part of a number. + /// Returns the integer part of `self`. + /// This means that non-integer numbers are always truncated towards zero. /// /// # Examples /// @@ -111,7 +112,7 @@ impl f32 { unsafe { intrinsics::truncf32(self) } } - /// Returns the fractional part of a number. + /// Returns the fractional part of `self`. /// /// # Examples /// @@ -132,8 +133,7 @@ impl f32 { self - self.trunc() } - /// Computes the absolute value of `self`. Returns `NAN` if the - /// number is `NAN`. + /// Computes the absolute value of `self`. /// /// # Examples /// @@ -161,7 +161,7 @@ impl f32 { /// /// - `1.0` if the number is positive, `+0.0` or `INFINITY` /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - `NAN` if the number is `NAN` + /// - NaN if the number is NaN /// /// # Examples /// @@ -185,8 +185,10 @@ impl f32 { /// `sign`. /// /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise - /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of - /// `sign` is returned. + /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of + /// `sign` is returned. Note, however, that conserving the sign bit on NaN + /// across arithmetical operations is not generally guaranteed. + /// See [explanation of NaN as a special value](primitive@f32) for more info. /// /// # Examples /// @@ -299,7 +301,9 @@ impl f32 { /// Raises a number to an integer power. /// - /// Using this function is generally faster than using `powf` + /// Using this function is generally faster than using `powf`. + /// It might have a different sequence of rounding operations than `powf`, + /// so the results are not guaranteed to agree. /// /// # Examples /// diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index b90d068ec10d3..d28bd386c2a4c 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -30,7 +30,7 @@ pub use core::f64::{ #[cfg(not(test))] #[cfg_attr(bootstrap, lang = "f64_runtime")] impl f64 { - /// Returns the largest integer less than or equal to a number. + /// Returns the largest integer less than or equal to `self`. /// /// # Examples /// @@ -51,7 +51,7 @@ impl f64 { unsafe { intrinsics::floorf64(self) } } - /// Returns the smallest integer greater than or equal to a number. + /// Returns the smallest integer greater than or equal to `self`. /// /// # Examples /// @@ -70,7 +70,7 @@ impl f64 { unsafe { intrinsics::ceilf64(self) } } - /// Returns the nearest integer to a number. Round half-way cases away from + /// Returns the nearest integer to `self`. Round half-way cases away from /// `0.0`. /// /// # Examples @@ -90,7 +90,8 @@ impl f64 { unsafe { intrinsics::roundf64(self) } } - /// Returns the integer part of a number. + /// Returns the integer part of `self`. + /// This means that non-integer numbers are always truncated towards zero. /// /// # Examples /// @@ -111,7 +112,7 @@ impl f64 { unsafe { intrinsics::truncf64(self) } } - /// Returns the fractional part of a number. + /// Returns the fractional part of `self`. /// /// # Examples /// @@ -132,8 +133,7 @@ impl f64 { self - self.trunc() } - /// Computes the absolute value of `self`. Returns `NAN` if the - /// number is `NAN`. + /// Computes the absolute value of `self`. /// /// # Examples /// @@ -161,7 +161,7 @@ impl f64 { /// /// - `1.0` if the number is positive, `+0.0` or `INFINITY` /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY` - /// - `NAN` if the number is `NAN` + /// - NaN if the number is NaN /// /// # Examples /// @@ -185,8 +185,10 @@ impl f64 { /// `sign`. /// /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise - /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of - /// `sign` is returned. + /// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of + /// `sign` is returned. Note, however, that conserving the sign bit on NaN + /// across arithmetical operations is not generally guaranteed. + /// See [explanation of NaN as a special value](primitive@f32) for more info. /// /// # Examples /// @@ -299,7 +301,9 @@ impl f64 { /// Raises a number to an integer power. /// - /// Using this function is generally faster than using `powf` + /// Using this function is generally faster than using `powf`. + /// It might have a different sequence of rounding operations than `powf`, + /// so the results are not guaranteed to agree. /// /// # Examples /// diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index 225a679efd221..ac4e668112b94 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -977,10 +977,22 @@ mod prim_tuple {} /// like `1.0 / 0.0`. /// - [NaN (not a number)](#associatedconstant.NAN): this value results from /// calculations like `(-1.0).sqrt()`. NaN has some potentially unexpected -/// behavior: it is unequal to any float, including itself! It is also neither -/// smaller nor greater than any float, making it impossible to sort. Lastly, -/// it is considered infectious as almost all calculations where one of the -/// operands is NaN will also result in NaN. +/// behavior: +/// - It is unequal to any float, including itself! This is the reason `f32` +/// doesn't implement the `Eq` trait. +/// - It is also neither smaller nor greater than any float, making it +/// impossible to sort by the default comparison operation, which is the +/// reason `f32` doesn't implement the `Ord` trait. +/// - It is also considered *infectious* as almost all calculations where one +/// of the operands is NaN will also result in NaN. The explanations on this +/// page only explicitly document behavior on NaN operands if this default +/// is deviated from. +/// - Lastly, there are multiple bit patterns that are considered NaN. +/// Rust does not currently guarantee that the bit patterns of NaN are +/// preserved over arithmetic operations, and they are not guaranteed to be +/// portable or even fully deterministic! This means that there may be some +/// surprising results upon inspecting the bit patterns, +/// as the same calculations might produce NaNs with different bit patterns. /// /// For more information on floating point numbers, see [Wikipedia][wikipedia]. ///