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 46e86c306fb1a..c3862d994986a 100644 --- a/library/core/src/num/f128.rs +++ b/library/core/src/num/f128.rs @@ -285,17 +285,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. /// @@ -345,10 +334,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]. @@ -836,8 +826,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 @@ -1281,4 +1271,100 @@ impl f128 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// #![feature(f128)] + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// 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] + #[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(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// 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] + #[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(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// 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] + #[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 { + // 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 91a9bb5cbbe1b..ed35316cf8f9c 100644 --- a/library/core/src/num/f16.rs +++ b/library/core/src/num/f16.rs @@ -279,15 +279,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. /// @@ -335,10 +326,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]. @@ -821,8 +813,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 @@ -1256,4 +1248,99 @@ impl f16 { } self } + + /// Computes the absolute value of `self`. + /// + /// This function always returns the precise result. + /// + /// # Examples + /// + /// ``` + /// #![feature(f16)] + /// # #[cfg(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// 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] + #[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(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// 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] + #[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(all(target_arch = "x86_64", target_os = "linux"))] { + /// + /// 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] + #[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 { + // 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 20ece883da60b..ae9e69f56fba5 100644 --- a/library/core/src/num/f32.rs +++ b/library/core/src/num/f32.rs @@ -525,15 +525,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. /// @@ -578,10 +569,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]. @@ -1019,8 +1011,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 @@ -1424,4 +1416,87 @@ 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()); + /// ``` + #[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 { + // SAFETY: this is actually a safe intrinsic + 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()); + /// ``` + #[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()); + /// ``` + #[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 { + // 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 5640e71788b85..98dcbffd3b49e 100644 --- a/library/core/src/num/f64.rs +++ b/library/core/src/num/f64.rs @@ -524,15 +524,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. /// @@ -577,10 +568,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]. @@ -1022,8 +1014,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 @@ -1424,4 +1416,87 @@ 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()); + /// ``` + #[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 { + // SAFETY: this is actually a safe intrinsic + 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()); + /// ``` + #[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()); + /// ``` + #[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 { + // SAFETY: this is actually a safe intrinsic + 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. ///