From e8dfe6e4f255308f07e86a87e309912474cd27e5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Oct 2024 20:39:15 +0200 Subject: [PATCH 1/5] float types: move copysign, abs, signum to libcore --- library/core/src/num/f128.rs | 98 ++++++++++++++++++++++++++++++++++++ library/core/src/num/f16.rs | 97 +++++++++++++++++++++++++++++++++++ library/core/src/num/f32.rs | 84 +++++++++++++++++++++++++++++++ library/core/src/num/f64.rs | 84 +++++++++++++++++++++++++++++++ library/std/src/f128.rs | 98 ------------------------------------ library/std/src/f16.rs | 97 ----------------------------------- library/std/src/f32.rs | 84 ------------------------------- library/std/src/f64.rs | 84 ------------------------------- 8 files changed, 363 insertions(+), 363 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index e8161cce2fe29..cbe1a6060de41 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1282,4 +1282,102 @@ impl f128 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// #![feature(f128)] + /// # #[cfg(reliable_f128)] { + /// + /// let x = 3.5_f128; + /// let y = -3.5_f128; + /// + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); + /// + /// assert!(f128::NAN.abs().is_nan()); + /// # } + /// ``` + #[inline] + #[rustc_allow_incoherent_impl] + #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn abs(self) -> Self { + // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available + // We don't do this now because LLVM has lowering bugs for f128 math. + Self::from_bits(self.to_bits() & !(1 << 127)) + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `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 + /// + /// # Examples + /// + /// ``` + /// #![feature(f128)] + /// # #[cfg(reliable_f128_math)] { + /// + /// let f = 3.5_f128; + /// + /// assert_eq!(f.signum(), 1.0); + /// assert_eq!(f128::NEG_INFINITY.signum(), -1.0); + /// + /// assert!(f128::NAN.signum().is_nan()); + /// # } + /// ``` + #[inline] + #[rustc_allow_incoherent_impl] + #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn signum(self) -> f128 { + if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) } + } + + /// Returns a number composed of the magnitude of `self` and the sign of + /// `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 same payload as `self` and the sign bit of `sign` is + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 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 `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. + /// + /// # Examples + /// + /// ``` + /// #![feature(f128)] + /// # #[cfg(reliable_f128_math)] { + /// + /// let f = 3.5_f128; + /// + /// assert_eq!(f.copysign(0.42), 3.5_f128); + /// assert_eq!(f.copysign(-0.42), -3.5_f128); + /// assert_eq!((-f).copysign(0.42), 3.5_f128); + /// assert_eq!((-f).copysign(-0.42), -3.5_f128); + /// + /// assert!(f128::NAN.copysign(1.0).is_nan()); + /// # } + /// ``` + #[inline] + #[rustc_allow_incoherent_impl] + #[unstable(feature = "f128", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn copysign(self, sign: f128) -> f128 { + unsafe { intrinsics::copysignf128(self, sign) } + } } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 8b3f3b7d19bf7..19263062c7572 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1257,4 +1257,101 @@ impl f16 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// #![feature(f16)] + /// # #[cfg(reliable_f16)] { + /// + /// let x = 3.5_f16; + /// let y = -3.5_f16; + /// + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); + /// + /// assert!(f16::NAN.abs().is_nan()); + /// # } + /// ``` + #[inline] + #[rustc_allow_incoherent_impl] + #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn abs(self) -> Self { + // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available + Self::from_bits(self.to_bits() & !(1 << 15)) + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `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 + /// + /// # Examples + /// + /// ``` + /// #![feature(f16)] + /// # #[cfg(reliable_f16_math)] { + /// + /// let f = 3.5_f16; + /// + /// assert_eq!(f.signum(), 1.0); + /// assert_eq!(f16::NEG_INFINITY.signum(), -1.0); + /// + /// assert!(f16::NAN.signum().is_nan()); + /// # } + /// ``` + #[inline] + #[rustc_allow_incoherent_impl] + #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn signum(self) -> f16 { + if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) } + } + + /// Returns a number composed of the magnitude of `self` and the sign of + /// `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 same payload as `self` and the sign bit of `sign` is + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 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 `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. + /// + /// # Examples + /// + /// ``` + /// #![feature(f16)] + /// # #[cfg(reliable_f16_math)] { + /// + /// let f = 3.5_f16; + /// + /// assert_eq!(f.copysign(0.42), 3.5_f16); + /// assert_eq!(f.copysign(-0.42), -3.5_f16); + /// assert_eq!((-f).copysign(0.42), 3.5_f16); + /// assert_eq!((-f).copysign(-0.42), -3.5_f16); + /// + /// assert!(f16::NAN.copysign(1.0).is_nan()); + /// # } + /// ``` + #[inline] + #[rustc_allow_incoherent_impl] + #[unstable(feature = "f16", issue = "116909")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[must_use = "method returns a new number and does not mutate the original value"] + pub const fn copysign(self, sign: f16) -> f16 { + unsafe { intrinsics::copysignf16(self, sign) } + } } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index a01761ee5d4a3..d9337af316ce8 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1427,4 +1427,88 @@ impl f32 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// let x = 3.5_f32; + /// let y = -3.5_f32; + /// + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); + /// + /// assert!(f32::NAN.abs().is_nan()); + /// ``` + #[rustc_allow_incoherent_impl] + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn abs(self) -> f32 { + unsafe { intrinsics::fabsf32(self) } + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `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 + /// + /// # Examples + /// + /// ``` + /// let f = 3.5_f32; + /// + /// assert_eq!(f.signum(), 1.0); + /// assert_eq!(f32::NEG_INFINITY.signum(), -1.0); + /// + /// assert!(f32::NAN.signum().is_nan()); + /// ``` + #[rustc_allow_incoherent_impl] + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn signum(self) -> f32 { + if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } + } + + /// Returns a number composed of the magnitude of `self` and the sign of + /// `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 same payload as `self` and the sign bit of `sign` is + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 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 `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. + /// + /// # Examples + /// + /// ``` + /// let f = 3.5_f32; + /// + /// assert_eq!(f.copysign(0.42), 3.5_f32); + /// assert_eq!(f.copysign(-0.42), -3.5_f32); + /// assert_eq!((-f).copysign(0.42), 3.5_f32); + /// assert_eq!((-f).copysign(-0.42), -3.5_f32); + /// + /// assert!(f32::NAN.copysign(1.0).is_nan()); + /// ``` + #[rustc_allow_incoherent_impl] + #[must_use = "method returns a new number and does not mutate the original value"] + #[inline] + #[stable(feature = "copysign", since = "1.35.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + pub const fn copysign(self, sign: f32) -> f32 { + unsafe { intrinsics::copysignf32(self, sign) } + } } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index 2995e41cd6ea0..bcab5193718d7 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1427,4 +1427,88 @@ impl f64 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// let x = 3.5_f64; + /// let y = -3.5_f64; + /// + /// assert_eq!(x.abs(), x); + /// assert_eq!(y.abs(), -y); + /// + /// assert!(f64::NAN.abs().is_nan()); + /// ``` + #[rustc_allow_incoherent_impl] + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn abs(self) -> f64 { + unsafe { intrinsics::fabsf64(self) } + } + + /// Returns a number that represents the sign of `self`. + /// + /// - `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 + /// + /// # Examples + /// + /// ``` + /// let f = 3.5_f64; + /// + /// assert_eq!(f.signum(), 1.0); + /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0); + /// + /// assert!(f64::NAN.signum().is_nan()); + /// ``` + #[rustc_allow_incoherent_impl] + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn signum(self) -> f64 { + if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) } + } + + /// Returns a number composed of the magnitude of `self` and the sign of + /// `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 same payload as `self` and the sign bit of `sign` is + /// returned. + /// + /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note + /// that IEEE 754 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 `copysign` with `sign` being a NaN might produce an unexpected or non-portable + /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more + /// info. + /// + /// # Examples + /// + /// ``` + /// let f = 3.5_f64; + /// + /// assert_eq!(f.copysign(0.42), 3.5_f64); + /// assert_eq!(f.copysign(-0.42), -3.5_f64); + /// assert_eq!((-f).copysign(0.42), 3.5_f64); + /// assert_eq!((-f).copysign(-0.42), -3.5_f64); + /// + /// assert!(f64::NAN.copysign(1.0).is_nan()); + /// ``` + #[rustc_allow_incoherent_impl] + #[must_use = "method returns a new number and does not mutate the original value"] + #[stable(feature = "copysign", since = "1.35.0")] + #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] + #[inline] + pub const fn copysign(self, sign: f64) -> f64 { + unsafe { intrinsics::copysignf64(self, sign) } + } } diff --git a/library/std/src/f128.rs b/library/std/src/f128.rs index 229f979b5b10b..e93e915159e40 100644 --- a/library/std/src/f128.rs +++ b/library/std/src/f128.rs @@ -188,104 +188,6 @@ impl f128 { self - self.trunc() } - /// Computes the absolute value of `self`. - /// - /// This function always returns the precise result. - /// - /// # Examples - /// - /// ``` - /// #![feature(f128)] - /// # #[cfg(reliable_f128)] { - /// - /// let x = 3.5_f128; - /// let y = -3.5_f128; - /// - /// assert_eq!(x.abs(), x); - /// assert_eq!(y.abs(), -y); - /// - /// assert!(f128::NAN.abs().is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn abs(self) -> Self { - // FIXME(f16_f128): replace with `intrinsics::fabsf128` when available - // We don't do this now because LLVM has lowering bugs for f128 math. - Self::from_bits(self.to_bits() & !(1 << 127)) - } - - /// Returns a number that represents the sign of `self`. - /// - /// - `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 - /// - /// # Examples - /// - /// ``` - /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { - /// - /// let f = 3.5_f128; - /// - /// assert_eq!(f.signum(), 1.0); - /// assert_eq!(f128::NEG_INFINITY.signum(), -1.0); - /// - /// assert!(f128::NAN.signum().is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn signum(self) -> f128 { - if self.is_nan() { Self::NAN } else { 1.0_f128.copysign(self) } - } - - /// Returns a number composed of the magnitude of `self` and the sign of - /// `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 same payload as `self` and the sign bit of `sign` is - /// returned. - /// - /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note - /// that IEEE 754 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 `copysign` with `sign` being a NaN might produce an unexpected or non-portable - /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more - /// info. - /// - /// # Examples - /// - /// ``` - /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { - /// - /// let f = 3.5_f128; - /// - /// assert_eq!(f.copysign(0.42), 3.5_f128); - /// assert_eq!(f.copysign(-0.42), -3.5_f128); - /// assert_eq!((-f).copysign(0.42), 3.5_f128); - /// assert_eq!((-f).copysign(-0.42), -3.5_f128); - /// - /// assert!(f128::NAN.copysign(1.0).is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f128", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn copysign(self, sign: f128) -> f128 { - unsafe { intrinsics::copysignf128(self, sign) } - } - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error, yielding a more accurate result than an unfused multiply-add. /// diff --git a/library/std/src/f16.rs b/library/std/src/f16.rs index bed21cda1cd91..5b7fcaa28e064 100644 --- a/library/std/src/f16.rs +++ b/library/std/src/f16.rs @@ -188,103 +188,6 @@ impl f16 { self - self.trunc() } - /// Computes the absolute value of `self`. - /// - /// This function always returns the precise result. - /// - /// # Examples - /// - /// ``` - /// #![feature(f16)] - /// # #[cfg(reliable_f16)] { - /// - /// let x = 3.5_f16; - /// let y = -3.5_f16; - /// - /// assert_eq!(x.abs(), x); - /// assert_eq!(y.abs(), -y); - /// - /// assert!(f16::NAN.abs().is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn abs(self) -> Self { - // FIXME(f16_f128): replace with `intrinsics::fabsf16` when available - Self::from_bits(self.to_bits() & !(1 << 15)) - } - - /// Returns a number that represents the sign of `self`. - /// - /// - `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 - /// - /// # Examples - /// - /// ``` - /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { - /// - /// let f = 3.5_f16; - /// - /// assert_eq!(f.signum(), 1.0); - /// assert_eq!(f16::NEG_INFINITY.signum(), -1.0); - /// - /// assert!(f16::NAN.signum().is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn signum(self) -> f16 { - if self.is_nan() { Self::NAN } else { 1.0_f16.copysign(self) } - } - - /// Returns a number composed of the magnitude of `self` and the sign of - /// `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 same payload as `self` and the sign bit of `sign` is - /// returned. - /// - /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note - /// that IEEE 754 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 `copysign` with `sign` being a NaN might produce an unexpected or non-portable - /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more - /// info. - /// - /// # Examples - /// - /// ``` - /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { - /// - /// let f = 3.5_f16; - /// - /// assert_eq!(f.copysign(0.42), 3.5_f16); - /// assert_eq!(f.copysign(-0.42), -3.5_f16); - /// assert_eq!((-f).copysign(0.42), 3.5_f16); - /// assert_eq!((-f).copysign(-0.42), -3.5_f16); - /// - /// assert!(f16::NAN.copysign(1.0).is_nan()); - /// # } - /// ``` - #[inline] - #[rustc_allow_incoherent_impl] - #[unstable(feature = "f16", issue = "116909")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[must_use = "method returns a new number and does not mutate the original value"] - pub const fn copysign(self, sign: f16) -> f16 { - unsafe { intrinsics::copysignf16(self, sign) } - } - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error, yielding a more accurate result than an unfused multiply-add. /// diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs index 30cf4e1f756e0..7cb285bbff5f7 100644 --- a/library/std/src/f32.rs +++ b/library/std/src/f32.rs @@ -176,90 +176,6 @@ impl f32 { self - self.trunc() } - /// Computes the absolute value of `self`. - /// - /// This function always returns the precise result. - /// - /// # Examples - /// - /// ``` - /// let x = 3.5_f32; - /// let y = -3.5_f32; - /// - /// assert_eq!(x.abs(), x); - /// assert_eq!(y.abs(), -y); - /// - /// assert!(f32::NAN.abs().is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn abs(self) -> f32 { - unsafe { intrinsics::fabsf32(self) } - } - - /// Returns a number that represents the sign of `self`. - /// - /// - `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 - /// - /// # Examples - /// - /// ``` - /// let f = 3.5_f32; - /// - /// assert_eq!(f.signum(), 1.0); - /// assert_eq!(f32::NEG_INFINITY.signum(), -1.0); - /// - /// assert!(f32::NAN.signum().is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn signum(self) -> f32 { - if self.is_nan() { Self::NAN } else { 1.0_f32.copysign(self) } - } - - /// Returns a number composed of the magnitude of `self` and the sign of - /// `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 same payload as `self` and the sign bit of `sign` is - /// returned. - /// - /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note - /// that IEEE 754 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 `copysign` with `sign` being a NaN might produce an unexpected or non-portable - /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more - /// info. - /// - /// # Examples - /// - /// ``` - /// let f = 3.5_f32; - /// - /// assert_eq!(f.copysign(0.42), 3.5_f32); - /// assert_eq!(f.copysign(-0.42), -3.5_f32); - /// assert_eq!((-f).copysign(0.42), 3.5_f32); - /// assert_eq!((-f).copysign(-0.42), -3.5_f32); - /// - /// assert!(f32::NAN.copysign(1.0).is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[inline] - #[stable(feature = "copysign", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - pub const fn copysign(self, sign: f32) -> f32 { - unsafe { intrinsics::copysignf32(self, sign) } - } - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error, yielding a more accurate result than an unfused multiply-add. /// diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs index 51d5476b372d2..47163c272de32 100644 --- a/library/std/src/f64.rs +++ b/library/std/src/f64.rs @@ -176,90 +176,6 @@ impl f64 { self - self.trunc() } - /// Computes the absolute value of `self`. - /// - /// This function always returns the precise result. - /// - /// # Examples - /// - /// ``` - /// let x = 3.5_f64; - /// let y = -3.5_f64; - /// - /// assert_eq!(x.abs(), x); - /// assert_eq!(y.abs(), -y); - /// - /// assert!(f64::NAN.abs().is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn abs(self) -> f64 { - unsafe { intrinsics::fabsf64(self) } - } - - /// Returns a number that represents the sign of `self`. - /// - /// - `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 - /// - /// # Examples - /// - /// ``` - /// let f = 3.5_f64; - /// - /// assert_eq!(f.signum(), 1.0); - /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0); - /// - /// assert!(f64::NAN.signum().is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "rust1", since = "1.0.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn signum(self) -> f64 { - if self.is_nan() { Self::NAN } else { 1.0_f64.copysign(self) } - } - - /// Returns a number composed of the magnitude of `self` and the sign of - /// `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 same payload as `self` and the sign bit of `sign` is - /// returned. - /// - /// If `sign` is a NaN, then this operation will still carry over its sign into the result. Note - /// that IEEE 754 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 `copysign` with `sign` being a NaN might produce an unexpected or non-portable - /// result. See the [specification of NaN bit patterns](primitive@f32#nan-bit-patterns) for more - /// info. - /// - /// # Examples - /// - /// ``` - /// let f = 3.5_f64; - /// - /// assert_eq!(f.copysign(0.42), 3.5_f64); - /// assert_eq!(f.copysign(-0.42), -3.5_f64); - /// assert_eq!((-f).copysign(0.42), 3.5_f64); - /// assert_eq!((-f).copysign(-0.42), -3.5_f64); - /// - /// assert!(f64::NAN.copysign(1.0).is_nan()); - /// ``` - #[rustc_allow_incoherent_impl] - #[must_use = "method returns a new number and does not mutate the original value"] - #[stable(feature = "copysign", since = "1.35.0")] - #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] - #[inline] - pub const fn copysign(self, sign: f64) -> f64 { - unsafe { intrinsics::copysignf64(self, sign) } - } - /// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// error, yielding a more accurate result than an unfused multiply-add. /// From f512051c0ecc1abe83a294a1b7ffed48a44b0ca6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Oct 2024 21:26:25 +0200 Subject: [PATCH 2/5] adjust test gating for f16/f128 --- library/core/src/num/f128.rs | 6 +++--- library/core/src/num/f16.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index cbe1a6060de41..a551ccfe9ed92 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1291,7 +1291,7 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128)] { + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// let x = 3.5_f128; /// let y = -3.5_f128; @@ -1323,7 +1323,7 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// let f = 3.5_f128; /// @@ -1360,7 +1360,7 @@ impl f128 { /// /// ``` /// #![feature(f128)] - /// # #[cfg(reliable_f128_math)] { + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// let f = 3.5_f128; /// diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 19263062c7572..0d77377af746e 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1266,7 +1266,7 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16)] { + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// let x = 3.5_f16; /// let y = -3.5_f16; @@ -1297,7 +1297,7 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// let f = 3.5_f16; /// @@ -1334,7 +1334,7 @@ impl f16 { /// /// ``` /// #![feature(f16)] - /// # #[cfg(reliable_f16_math)] { + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { /// /// let f = 3.5_f16; /// From b0224fb794f2aaa1449f02b873976c95b04eeca0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 5 Oct 2024 21:35:04 +0200 Subject: [PATCH 3/5] add missing safety comments --- library/core/src/num/f128.rs | 1 + library/core/src/num/f16.rs | 1 + library/core/src/num/f32.rs | 2 ++ library/core/src/num/f64.rs | 2 ++ 4 files changed, 6 insertions(+) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index a551ccfe9ed92..90d3035f15731 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1378,6 +1378,7 @@ impl f128 { #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn copysign(self, sign: f128) -> f128 { + // SAFETY: this is actually a safe intrinsic unsafe { intrinsics::copysignf128(self, sign) } } } diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 0d77377af746e..85b2ad18886a5 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1352,6 +1352,7 @@ impl f16 { #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] pub const fn copysign(self, sign: f16) -> f16 { + // SAFETY: this is actually a safe intrinsic unsafe { intrinsics::copysignf16(self, sign) } } } diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index d9337af316ce8..51241fa102788 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1449,6 +1449,7 @@ impl f32 { #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] pub const fn abs(self) -> f32 { + // SAFETY: this is actually a safe intrinsic unsafe { intrinsics::fabsf32(self) } } @@ -1509,6 +1510,7 @@ impl f32 { #[stable(feature = "copysign", since = "1.35.0")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] pub const fn copysign(self, sign: f32) -> f32 { + // SAFETY: this is actually a safe intrinsic unsafe { intrinsics::copysignf32(self, sign) } } } diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index bcab5193718d7..f42eaf8317747 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1449,6 +1449,7 @@ impl f64 { #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] pub const fn abs(self) -> f64 { + // SAFETY: this is actually a safe intrinsic unsafe { intrinsics::fabsf64(self) } } @@ -1509,6 +1510,7 @@ impl f64 { #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[inline] pub const fn copysign(self, sign: f64) -> f64 { + // SAFETY: this is actually a safe intrinsic unsafe { intrinsics::copysignf64(self, sign) } } } From 7d7c0541b93df64f703c646a931488df5ce88d45 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 1 Nov 2024 16:50:11 +0100 Subject: [PATCH 4/5] remove no-longer-needed attribute --- library/core/src/num/f128.rs | 3 --- library/core/src/num/f16.rs | 3 --- library/core/src/num/f32.rs | 3 --- library/core/src/num/f64.rs | 3 --- 4 files changed, 12 deletions(-) diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index 90d3035f15731..a1e6079a37d5e 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -1303,7 +1303,6 @@ impl f128 { /// # } /// ``` #[inline] - #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] @@ -1334,7 +1333,6 @@ impl f128 { /// # } /// ``` #[inline] - #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] @@ -1373,7 +1371,6 @@ impl f128 { /// # } /// ``` #[inline] - #[rustc_allow_incoherent_impl] #[unstable(feature = "f128", issue = "116909")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 85b2ad18886a5..77dc8bddf164a 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -1278,7 +1278,6 @@ impl f16 { /// # } /// ``` #[inline] - #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] @@ -1308,7 +1307,6 @@ impl f16 { /// # } /// ``` #[inline] - #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] @@ -1347,7 +1345,6 @@ impl f16 { /// # } /// ``` #[inline] - #[rustc_allow_incoherent_impl] #[unstable(feature = "f16", issue = "116909")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] #[must_use = "method returns a new number and does not mutate the original value"] diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 51241fa102788..953deb037b76b 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -1443,7 +1443,6 @@ impl f32 { /// /// assert!(f32::NAN.abs().is_nan()); /// ``` - #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] @@ -1469,7 +1468,6 @@ impl f32 { /// /// assert!(f32::NAN.signum().is_nan()); /// ``` - #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] @@ -1504,7 +1502,6 @@ impl f32 { /// /// assert!(f32::NAN.copysign(1.0).is_nan()); /// ``` - #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[inline] #[stable(feature = "copysign", since = "1.35.0")] diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index f42eaf8317747..edcf7b9dc9633 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -1443,7 +1443,6 @@ impl f64 { /// /// assert!(f64::NAN.abs().is_nan()); /// ``` - #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] @@ -1469,7 +1468,6 @@ impl f64 { /// /// assert!(f64::NAN.signum().is_nan()); /// ``` - #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] @@ -1504,7 +1502,6 @@ impl f64 { /// /// assert!(f64::NAN.copysign(1.0).is_nan()); /// ``` - #[rustc_allow_incoherent_impl] #[must_use = "method returns a new number and does not mutate the original value"] #[stable(feature = "copysign", since = "1.35.0")] #[rustc_const_unstable(feature = "const_float_methods", issue = "130843")] From 2d3c08a02216693f26b5a8c3c44bb8a6be8abc0b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 12 Nov 2024 07:22:49 +0100 Subject: [PATCH 5/5] remove no-longer-needed abs_private --- library/core/src/fmt/float.rs | 2 +- library/core/src/num/f128.rs | 18 ++++-------------- library/core/src/num/f16.rs | 16 ++++------------ library/core/src/num/f32.rs | 16 ++++------------ library/core/src/num/f64.rs | 16 ++++------------ 5 files changed, 17 insertions(+), 51 deletions(-) diff --git a/library/core/src/fmt/float.rs b/library/core/src/fmt/float.rs index c70dbf54304de..04230b1610aae 100644 --- a/library/core/src/fmt/float.rs +++ b/library/core/src/fmt/float.rs @@ -13,7 +13,7 @@ macro_rules! impl_general_format { ($($t:ident)*) => { $(impl GeneralFormat for $t { fn already_rounded_value_should_use_exponential(&self) -> bool { - let abs = $t::abs_private(*self); + let abs = $t::abs(*self); (abs != 0.0 && abs < 1e-4) || abs >= 1e+16 } })* diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs index a1e6079a37d5e..7bbdc3db6d694 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -284,17 +284,6 @@ impl f128 { self != self } - // FIXME(#50145): `abs` is publicly unavailable in core due to - // concerns about portability, so this implementation is for - // private use internally. - #[inline] - pub(crate) const fn abs_private(self) -> f128 { - // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`. - unsafe { - mem::transmute::(mem::transmute::(self) & !Self::SIGN_MASK) - } - } - /// Returns `true` if this value is positive infinity or negative infinity, and /// `false` otherwise. /// @@ -344,10 +333,11 @@ impl f128 { #[inline] #[must_use] #[unstable(feature = "f128", issue = "116909")] + #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < Self::INFINITY + self.abs() < Self::INFINITY } /// Returns `true` if the number is [subnormal]. @@ -835,8 +825,8 @@ impl f128 { const HI: f128 = f128::MAX / 2.; let (a, b) = (self, other); - let abs_a = a.abs_private(); - let abs_b = b.abs_private(); + let abs_a = a.abs(); + let abs_b = b.abs(); if abs_a <= HI && abs_b <= HI { // Overflow is impossible diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs index 77dc8bddf164a..786ac147f3862 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -278,15 +278,6 @@ impl f16 { self != self } - // FIXMxE(#50145): `abs` is publicly unavailable in core due to - // concerns about portability, so this implementation is for - // private use internally. - #[inline] - pub(crate) const fn abs_private(self) -> f16 { - // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`. - unsafe { mem::transmute::(mem::transmute::(self) & !Self::SIGN_MASK) } - } - /// Returns `true` if this value is positive infinity or negative infinity, and /// `false` otherwise. /// @@ -334,10 +325,11 @@ impl f16 { #[inline] #[must_use] #[unstable(feature = "f16", issue = "116909")] + #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < Self::INFINITY + self.abs() < Self::INFINITY } /// Returns `true` if the number is [subnormal]. @@ -820,8 +812,8 @@ impl f16 { const HI: f16 = f16::MAX / 2.; let (a, b) = (self, other); - let abs_a = a.abs_private(); - let abs_b = b.abs_private(); + let abs_a = a.abs(); + let abs_b = b.abs(); if abs_a <= HI && abs_b <= HI { // Overflow is impossible diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs index 953deb037b76b..2e6305354b43a 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -524,15 +524,6 @@ impl f32 { self != self } - // FIXME(#50145): `abs` is publicly unavailable in core due to - // concerns about portability, so this implementation is for - // private use internally. - #[inline] - pub(crate) const fn abs_private(self) -> f32 { - // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`. - unsafe { mem::transmute::(mem::transmute::(self) & !Self::SIGN_MASK) } - } - /// Returns `true` if this value is positive infinity or negative infinity, and /// `false` otherwise. /// @@ -577,10 +568,11 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] + #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < Self::INFINITY + self.abs() < Self::INFINITY } /// Returns `true` if the number is [subnormal]. @@ -1020,8 +1012,8 @@ impl f32 { const HI: f32 = f32::MAX / 2.; let (a, b) = (self, other); - let abs_a = a.abs_private(); - let abs_b = b.abs_private(); + let abs_a = a.abs(); + let abs_b = b.abs(); if abs_a <= HI && abs_b <= HI { // Overflow is impossible diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs index edcf7b9dc9633..67ef48f9ed791 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -523,15 +523,6 @@ impl f64 { self != self } - // FIXME(#50145): `abs` is publicly unavailable in core due to - // concerns about portability, so this implementation is for - // private use internally. - #[inline] - pub(crate) const fn abs_private(self) -> f64 { - // SAFETY: This transmutation is fine just like in `to_bits`/`from_bits`. - unsafe { mem::transmute::(mem::transmute::(self) & !Self::SIGN_MASK) } - } - /// Returns `true` if this value is positive infinity or negative infinity, and /// `false` otherwise. /// @@ -576,10 +567,11 @@ impl f64 { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_float_classify", since = "1.83.0")] #[inline] + #[rustc_allow_const_fn_unstable(const_float_methods)] // for `abs` pub const fn is_finite(self) -> bool { // There's no need to handle NaN separately: if self is NaN, // the comparison is not true, exactly as desired. - self.abs_private() < Self::INFINITY + self.abs() < Self::INFINITY } /// Returns `true` if the number is [subnormal]. @@ -1023,8 +1015,8 @@ impl f64 { const HI: f64 = f64::MAX / 2.; let (a, b) = (self, other); - let abs_a = a.abs_private(); - let abs_b = b.abs_private(); + let abs_a = a.abs(); + let abs_b = b.abs(); if abs_a <= HI && abs_b <= HI { // Overflow is impossible