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

Improve floating point documentation #95483

Merged
merged 8 commits into from
May 9, 2022
79 changes: 60 additions & 19 deletions library/core/src/num/f32.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 (∞).
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -672,47 +689,47 @@ 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;
/// let y = 2.0f32;
///
/// 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]
pub fn max(self, other: f32) -> 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;
/// let y = 2.0f32;
///
/// 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]
pub fn min(self, other: f32) -> 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.
Expand All @@ -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]
Expand All @@ -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.
Expand All @@ -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]
Expand Down Expand Up @@ -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
///
/// ```
Expand All @@ -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
///
/// ```
Expand All @@ -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
///
/// ```
Expand All @@ -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
///
/// ```
Expand All @@ -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
///
/// ```
Expand All @@ -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
///
/// ```
Expand Down
Loading