mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Rollup merge of #63786 - tspiteri:const-abs, r=alexcrichton
Make `abs`, `wrapping_abs`, `overflowing_abs` const functions This makes `abs`, `wrapping_abs` and `overflowing_abs` const functions like #58044 makes `wrapping_neg` and `overflowing_neg` const functions. `abs` is made const by returning `(self ^ -1) - -1` = `!self + 1` = `-self` for negative numbers and `(self ^ 0) - 0` = `self` for non-negative numbers. The subexpression `self >> ($BITS - 1)` evaluates to `-1` for negative numbers and `0` otherwise. The subtraction overflows when `self` is `min_value()`, as we would be subtracting `max_value() - -1`; this is when `abs` should overflow. `wrapping_abs` and `overflowing_abs` make use of `wrapping_sub` and `overflowing_sub` instead of the subtraction operator.
This commit is contained in:
commit
13726cc444
@ -1401,12 +1401,8 @@ $EndFeature, "
|
||||
```"),
|
||||
#[stable(feature = "no_panic_abs", since = "1.13.0")]
|
||||
#[inline]
|
||||
pub fn wrapping_abs(self) -> Self {
|
||||
if self.is_negative() {
|
||||
self.wrapping_neg()
|
||||
} else {
|
||||
self
|
||||
}
|
||||
pub const fn wrapping_abs(self) -> Self {
|
||||
(self ^ (self >> ($BITS - 1))).wrapping_sub(self >> ($BITS - 1))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1764,12 +1760,8 @@ $EndFeature, "
|
||||
```"),
|
||||
#[stable(feature = "no_panic_abs", since = "1.13.0")]
|
||||
#[inline]
|
||||
pub fn overflowing_abs(self) -> (Self, bool) {
|
||||
if self.is_negative() {
|
||||
self.overflowing_neg()
|
||||
} else {
|
||||
(self, false)
|
||||
}
|
||||
pub const fn overflowing_abs(self) -> (Self, bool) {
|
||||
(self ^ (self >> ($BITS - 1))).overflowing_sub(self >> ($BITS - 1))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1973,15 +1965,11 @@ $EndFeature, "
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
#[rustc_inherit_overflow_checks]
|
||||
pub fn abs(self) -> Self {
|
||||
if self.is_negative() {
|
||||
// Note that the #[inline] above means that the overflow
|
||||
// semantics of this negation depend on the crate we're being
|
||||
// inlined into.
|
||||
-self
|
||||
} else {
|
||||
self
|
||||
}
|
||||
pub const fn abs(self) -> Self {
|
||||
// Note that the #[inline] above means that the overflow
|
||||
// semantics of the subtraction depend on the crate we're being
|
||||
// inlined into.
|
||||
(self ^ (self >> ($BITS - 1))) - (self >> ($BITS - 1))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,10 @@ const SHR_B: (u32, bool) = 0x10u32.overflowing_shr(132);
|
||||
const NEG_A: (u32, bool) = 0u32.overflowing_neg();
|
||||
const NEG_B: (u32, bool) = core::u32::MAX.overflowing_neg();
|
||||
|
||||
const ABS_POS: (i32, bool) = 10i32.overflowing_abs();
|
||||
const ABS_NEG: (i32, bool) = (-10i32).overflowing_abs();
|
||||
const ABS_MIN: (i32, bool) = i32::min_value().overflowing_abs();
|
||||
|
||||
fn main() {
|
||||
assert_eq!(ADD_A, (7, false));
|
||||
assert_eq!(ADD_B, (0, true));
|
||||
@ -36,4 +40,8 @@ fn main() {
|
||||
|
||||
assert_eq!(NEG_A, (0, false));
|
||||
assert_eq!(NEG_B, (1, true));
|
||||
|
||||
assert_eq!(ABS_POS, (10, false));
|
||||
assert_eq!(ABS_NEG, (10, false));
|
||||
assert_eq!(ABS_MIN, (i32::min_value(), true));
|
||||
}
|
||||
|
@ -11,6 +11,9 @@ const SIGNUM_POS: i32 = 10i32.signum();
|
||||
const SIGNUM_NIL: i32 = 0i32.signum();
|
||||
const SIGNUM_NEG: i32 = (-42i32).signum();
|
||||
|
||||
const ABS_A: i32 = 10i32.abs();
|
||||
const ABS_B: i32 = (-10i32).abs();
|
||||
|
||||
fn main() {
|
||||
assert!(NEGATIVE_A);
|
||||
assert!(!NEGATIVE_B);
|
||||
@ -20,4 +23,7 @@ fn main() {
|
||||
assert_eq!(SIGNUM_POS, 1);
|
||||
assert_eq!(SIGNUM_NIL, 0);
|
||||
assert_eq!(SIGNUM_NEG, -1);
|
||||
|
||||
assert_eq!(ABS_A, 10);
|
||||
assert_eq!(ABS_B, 10);
|
||||
}
|
||||
|
@ -18,6 +18,10 @@ const SHR_B: u32 = 128u32.wrapping_shr(128);
|
||||
const NEG_A: u32 = 5u32.wrapping_neg();
|
||||
const NEG_B: u32 = 1234567890u32.wrapping_neg();
|
||||
|
||||
const ABS_POS: i32 = 10i32.wrapping_abs();
|
||||
const ABS_NEG: i32 = (-10i32).wrapping_abs();
|
||||
const ABS_MIN: i32 = i32::min_value().wrapping_abs();
|
||||
|
||||
fn main() {
|
||||
assert_eq!(ADD_A, 255);
|
||||
assert_eq!(ADD_B, 199);
|
||||
@ -36,4 +40,8 @@ fn main() {
|
||||
|
||||
assert_eq!(NEG_A, 4294967291);
|
||||
assert_eq!(NEG_B, 3060399406);
|
||||
|
||||
assert_eq!(ABS_POS, 10);
|
||||
assert_eq!(ABS_NEG, 10);
|
||||
assert_eq!(ABS_MIN, i32::min_value());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user