From 7eb76995933ee0ced03c23cdaeeeac86d7713450 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 18 Dec 2015 10:24:06 -0800 Subject: [PATCH] std: Move overflowing ops to inherent methods This commit migrates all of the methods on `num::wrapping::OverflowingOps` onto inherent methods of the integer types. This also fills out some missing gaps in the saturating and checked departments such as: * `saturating_mul` * `checked_{neg,rem,shl,shr}` This is done in preparation for stabilization, cc #27755 --- src/libcore/num/mod.rs | 672 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 658 insertions(+), 14 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index f180a513b86..76214366dc6 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -124,7 +124,7 @@ macro_rules! checked_op { // `Int` + `SignedInt` implemented for signed integers macro_rules! int_impl { - ($ActualT:ty, $UnsignedT:ty, $BITS:expr, + ($ActualT:ident, $UnsignedT:ty, $BITS:expr, $add_with_overflow:path, $sub_with_overflow:path, $mul_with_overflow:path) => { @@ -393,7 +393,8 @@ pub fn to_le(self) -> Self { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn checked_add(self, other: Self) -> Option { - checked_op!($ActualT, $add_with_overflow, self, other) + let (a, b) = self.overflowing_add(other); + if b {None} else {Some(a)} } /// Checked integer subtraction. Computes `self - other`, returning @@ -410,7 +411,8 @@ pub fn checked_add(self, other: Self) -> Option { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn checked_sub(self, other: Self) -> Option { - checked_op!($ActualT, $sub_with_overflow, self, other) + let (a, b) = self.overflowing_sub(other); + if b {None} else {Some(a)} } /// Checked integer multiplication. Computes `self * other`, returning @@ -427,7 +429,8 @@ pub fn checked_sub(self, other: Self) -> Option { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn checked_mul(self, other: Self) -> Option { - checked_op!($ActualT, $mul_with_overflow, self, other) + let (a, b) = self.overflowing_mul(other); + if b {None} else {Some(a)} } /// Checked integer division. Computes `self / other`, returning `None` @@ -445,14 +448,103 @@ pub fn checked_mul(self, other: Self) -> Option { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn checked_div(self, other: Self) -> Option { - match other { - 0 => None, - -1 if self == Self::min_value() - => None, - other => Some(self / other), + if other == 0 { + None + } else { + let (a, b) = self.overflowing_div(other); + if b {None} else {Some(a)} } } + /// Checked integer remainder. Computes `self % other`, returning `None` + /// if `other == 0` or the operation results in underflow or overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::i32; + /// + /// assert_eq!(5i32.checked_rem(2), Some(1)); + /// assert_eq!(5i32.checked_rem(0), None); + /// assert_eq!(i32::MIN.checked_rem(-1), None); + /// ``` + #[unstable(feature = "wrapping", issue = "27755")] + #[inline] + pub fn checked_rem(self, other: Self) -> Option { + if other == 0 { + None + } else { + let (a, b) = self.overflowing_rem(other); + if b {None} else {Some(a)} + } + } + + /// Checked negation. Computes `!self`, returning `None` if `self == + /// MIN`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::i32; + /// + /// assert_eq!(5i32.checked_neg(), Some(-5)); + /// assert_eq!(i32::MIN.checked_neg(), None); + /// ``` + #[unstable(feature = "wrapping", issue = "27755")] + #[inline] + pub fn checked_neg(self) -> Option { + let (a, b) = self.overflowing_neg(); + if b {None} else {Some(a)} + } + + /// Checked shift left. Computes `self << rhs`, returning `None` + /// if `rhs` is larger than or equal to the number of bits in `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(0x10i32.checked_shl(4), Some(0x100)); + /// assert_eq!(0x10i32.checked_shl(33), None); + /// ``` + #[unstable(feature = "wrapping", issue = "27755")] + #[inline] + pub fn checked_shl(self, rhs: u32) -> Option { + let (a, b) = self.overflowing_shl(rhs); + if b {None} else {Some(a)} + } + + /// Checked shift right. Computes `self >> rhs`, returning `None` + /// if `rhs` is larger than or equal to the number of bits in `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(0x10i32.checked_shr(4), Some(0x1)); + /// assert_eq!(0x10i32.checked_shr(33), None); + /// ``` + #[unstable(feature = "wrapping", issue = "27755")] + #[inline] + pub fn checked_shr(self, rhs: u32) -> Option { + let (a, b) = self.overflowing_shr(rhs); + if b {None} else {Some(a)} + } + /// Saturating integer addition. Computes `self + other`, saturating at /// the numeric bounds instead of overflowing. /// @@ -468,7 +560,7 @@ pub fn checked_div(self, other: Self) -> Option { #[inline] pub fn saturating_add(self, other: Self) -> Self { match self.checked_add(other) { - Some(x) => x, + Some(x) => x, None if other >= Self::zero() => Self::max_value(), None => Self::min_value(), } @@ -489,12 +581,40 @@ pub fn saturating_add(self, other: Self) -> Self { #[inline] pub fn saturating_sub(self, other: Self) -> Self { match self.checked_sub(other) { - Some(x) => x, + Some(x) => x, None if other >= Self::zero() => Self::min_value(), None => Self::max_value(), } } + /// Saturating integer multiplication. Computes `self * other`, + /// saturating at the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::i32; + /// + /// assert_eq!(100i32.saturating_mul(127), 12700); + /// assert_eq!((1i32 << 23).saturating_mul(1 << 23), i32::MAX); + /// assert_eq!((-1i32 << 23).saturating_mul(1 << 23), i32::MIN); + /// ``` + #[unstable(feature = "wrapping", issue = "27755")] + #[inline] + pub fn saturating_mul(self, other: Self) -> Self { + self.checked_mul(other).unwrap_or_else(|| { + if (self < 0 && other < 0) || (self > 0 && other > 0) { + Self::max_value() + } else { + Self::min_value() + } + }) + } + /// Wrapping (modular) addition. Computes `self + other`, /// wrapping around at the boundary of the type. /// @@ -562,6 +682,10 @@ pub fn wrapping_mul(self, rhs: Self) -> Self { /// in the type. In such a case, this function returns `MIN` /// itself. /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// /// # Examples /// /// Basic usage: @@ -584,6 +708,10 @@ pub fn wrapping_div(self, rhs: Self) -> Self { /// -1` on a signed type (where `MIN` is the negative /// minimal value). In such a case, this function returns `0`. /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// /// # Examples /// /// Basic usage: @@ -657,6 +785,230 @@ pub fn wrapping_shr(self, rhs: u32) -> Self { self.overflowing_shr(rhs).0 } + /// Calculates `self` + `rhs` + /// + /// Returns a tuple of the addition along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::i32; + /// + /// assert_eq!(5i32.overflowing_add(2), (7, false)); + /// assert_eq!(i32::MAX.overflowing_add(1), (i32::MIN, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $add_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates `self` - `rhs` + /// + /// Returns a tuple of the subtraction along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::i32; + /// + /// assert_eq!(5i32.overflowing_sub(2), (3, false)); + /// assert_eq!(i32::MIN.overflowing_sub(1), (i32::MAX, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $sub_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates the multiplication of `self` and `rhs`. + /// + /// Returns a tuple of the multiplication along with a boolean + /// indicating whether an arithmetic overflow would occur. If an + /// overflow would have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(5i32.overflowing_mul(2), (10, false)); + /// assert_eq!(1_000_000_000i32.overflowing_mul(10), (1410065408, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $mul_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates the divisor when `self` is divided by `rhs`. + /// + /// Returns a tuple of the divisor along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// occur then self is returned. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::i32; + /// + /// assert_eq!(5i32.overflowing_div(2), (2, false)); + /// assert_eq!(i32::MIN.overflowing_div(-1), (i32::MIN, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + if self == Self::min_value() && rhs == -1 { + (self, true) + } else { + (self / rhs, false) + } + } + + /// Calculates the remainder when `self` is divided by `rhs`. + /// + /// Returns a tuple of the remainder after dividing along with a boolean + /// indicating whether an arithmetic overflow would occur. If an + /// overflow would occur then 0 is returned. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::i32; + /// + /// assert_eq!(5i32.overflowing_rem(2), (1, false)); + /// assert_eq!(i32::MIN.overflowing_rem(-1), (0, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + if self == Self::min_value() && rhs == -1 { + (0, true) + } else { + (self % rhs, false) + } + } + + /// Negates self, overflowing if this is equal to the minimum value. + /// + /// Returns a tuple of the negated version of self along with a boolean + /// indicating whether an overflow happened. If `self` is the minimum + /// value (e.g. `i32::MIN` for values of type `i32`), then the minimum + /// value will be returned again and `true` will be returned for an + /// overflow happening. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::i32; + /// + /// assert_eq!(2i32.overflowing_neg(), (-2, false)); + /// assert_eq!(i32::MIN.overflowing_neg(), (i32::MIN, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_neg(self) -> (Self, bool) { + if self == Self::min_value() { + (Self::min_value(), true) + } else { + (-self, false) + } + } + + /// Shifts self left by `rhs` bits. + /// + /// Returns a tuple of the shifted version of self along with a boolean + /// indicating whether the shift value was larger than or equal to the + /// number of bits. If the shift value is too large, then value is + /// masked (N-1) where N is the number of bits, and this value is then + /// used to perform the shift. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(0x10i32.overflowing_shl(4), (0x100, false)); + /// assert_eq!(0x10i32.overflowing_shl(36), (0x100, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { + (self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) + } + + /// Shifts self right by `rhs` bits. + /// + /// Returns a tuple of the shifted version of self along with a boolean + /// indicating whether the shift value was larger than or equal to the + /// number of bits. If the shift value is too large, then value is + /// masked (N-1) where N is the number of bits, and this value is then + /// used to perform the shift. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(0x10i32.overflowing_shr(4), (0x1, false)); + /// assert_eq!(0x10i32.overflowing_shr(36), (0x1, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { + (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) + } + /// Raises self to the power of `exp`, using exponentiation by squaring. /// /// # Examples @@ -1121,7 +1473,8 @@ pub fn to_le(self) -> Self { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn checked_add(self, other: Self) -> Option { - checked_op!($ActualT, $add_with_overflow, self, other) + let (a, b) = self.overflowing_add(other); + if b {None} else {Some(a)} } /// Checked integer subtraction. Computes `self - other`, returning @@ -1138,7 +1491,8 @@ pub fn checked_add(self, other: Self) -> Option { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn checked_sub(self, other: Self) -> Option { - checked_op!($ActualT, $sub_with_overflow, self, other) + let (a, b) = self.overflowing_sub(other); + if b {None} else {Some(a)} } /// Checked integer multiplication. Computes `self * other`, returning @@ -1155,7 +1509,8 @@ pub fn checked_sub(self, other: Self) -> Option { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn checked_mul(self, other: Self) -> Option { - checked_op!($ActualT, $mul_with_overflow, self, other) + let (a, b) = self.overflowing_mul(other); + if b {None} else {Some(a)} } /// Checked integer division. Computes `self / other`, returning `None` @@ -1179,6 +1534,69 @@ pub fn checked_div(self, other: Self) -> Option { } } + /// Checked integer remainder. Computes `self % other`, returning `None` + /// if `other == 0` or the operation results in underflow or overflow. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(5u32.checked_rem(2), Some(1)); + /// assert_eq!(5u32.checked_rem(0), None); + /// ``` + #[unstable(feature = "wrapping", issue = "27755")] + #[inline] + pub fn checked_rem(self, other: Self) -> Option { + if other == 0 { + None + } else { + Some(self % other) + } + } + + /// Checked shift left. Computes `self << rhs`, returning `None` + /// if `rhs` is larger than or equal to the number of bits in `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(0x10u32.checked_shl(4), Some(0x100)); + /// assert_eq!(0x10u32.checked_shl(33), None); + /// ``` + #[unstable(feature = "wrapping", issue = "27755")] + #[inline] + pub fn checked_shl(self, rhs: u32) -> Option { + let (a, b) = self.overflowing_shl(rhs); + if b {None} else {Some(a)} + } + + /// Checked shift right. Computes `self >> rhs`, returning `None` + /// if `rhs` is larger than or equal to the number of bits in `self`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(0x10u32.checked_shr(4), Some(0x1)); + /// assert_eq!(0x10u32.checked_shr(33), None); + /// ``` + #[unstable(feature = "wrapping", issue = "27755")] + #[inline] + pub fn checked_shr(self, rhs: u32) -> Option { + let (a, b) = self.overflowing_shr(rhs); + if b {None} else {Some(a)} + } + /// Saturating integer addition. Computes `self + other`, saturating at /// the numeric bounds instead of overflowing. /// @@ -1221,6 +1639,27 @@ pub fn saturating_sub(self, other: Self) -> Self { } } + /// Saturating integer multiplication. Computes `self * other`, + /// saturating at the numeric bounds instead of overflowing. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::u32; + /// + /// assert_eq!(100u32.saturating_mul(127), 12700); + /// assert_eq!((1u32 << 23).saturating_mul(1 << 23), u32::MAX); + /// ``` + #[unstable(feature = "wrapping", issue = "27755")] + #[inline] + pub fn saturating_mul(self, other: Self) -> Self { + self.checked_mul(other).unwrap_or(Self::max_value()) + } + /// Wrapping (modular) addition. Computes `self + other`, /// wrapping around at the boundary of the type. /// @@ -1383,6 +1822,211 @@ pub fn wrapping_shr(self, rhs: u32) -> Self { self.overflowing_shr(rhs).0 } + /// Calculates `self` + `rhs` + /// + /// Returns a tuple of the addition along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::u32; + /// + /// assert_eq!(5u32.overflowing_add(2), (7, false)); + /// assert_eq!(u32::MAX.overflowing_add(1), (0, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_add(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $add_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates `self` - `rhs` + /// + /// Returns a tuple of the subtraction along with a boolean indicating + /// whether an arithmetic overflow would occur. If an overflow would + /// have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// use std::u32; + /// + /// assert_eq!(5u32.overflowing_sub(2), (3, false)); + /// assert_eq!(0u32.overflowing_sub(1), (u32::MAX, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_sub(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $sub_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates the multiplication of `self` and `rhs`. + /// + /// Returns a tuple of the multiplication along with a boolean + /// indicating whether an arithmetic overflow would occur. If an + /// overflow would have occurred then the wrapped value is returned. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(5u32.overflowing_mul(2), (10, false)); + /// assert_eq!(1_000_000_000u32.overflowing_mul(10), (1410065408, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_mul(self, rhs: Self) -> (Self, bool) { + unsafe { + let (a, b) = $mul_with_overflow(self as $ActualT, + rhs as $ActualT); + (a as Self, b) + } + } + + /// Calculates the divisor when `self` is divided by `rhs`. + /// + /// Returns a tuple of the divisor along with a boolean indicating + /// whether an arithmetic overflow would occur. Note that for unsigned + /// integers overflow never occurs, so the second value is always + /// `false`. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(5u32.overflowing_div(2), (2, false)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_div(self, rhs: Self) -> (Self, bool) { + (self / rhs, false) + } + + /// Calculates the remainder when `self` is divided by `rhs`. + /// + /// Returns a tuple of the remainder after dividing along with a boolean + /// indicating whether an arithmetic overflow would occur. Note that for + /// unsigned integers overflow never occurs, so the second value is + /// always `false`. + /// + /// # Panics + /// + /// This function will panic if `rhs` is 0. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(5u32.overflowing_rem(2), (1, false)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_rem(self, rhs: Self) -> (Self, bool) { + (self % rhs, false) + } + + /// Negates self in an overflowing fashion. + /// + /// Returns `!self + 1` using wrapping operations to return the value + /// that represents the negation of this unsigned value. Note that for + /// positive unsigned values overflow always occurs, but negating 0 does + /// not overflow. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(0u32.overflowing_neg(), (0, false)); + /// assert_eq!(2u32.overflowing_neg(), (-2i32 as u32, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_neg(self) -> (Self, bool) { + ((!self).wrapping_add(1), self != 0) + } + + /// Shifts self left by `rhs` bits. + /// + /// Returns a tuple of the shifted version of self along with a boolean + /// indicating whether the shift value was larger than or equal to the + /// number of bits. If the shift value is too large, then value is + /// masked (N-1) where N is the number of bits, and this value is then + /// used to perform the shift. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(0x10u32.overflowing_shl(4), (0x100, false)); + /// assert_eq!(0x10u32.overflowing_shl(36), (0x100, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_shl(self, rhs: u32) -> (Self, bool) { + (self << (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) + } + + /// Shifts self right by `rhs` bits. + /// + /// Returns a tuple of the shifted version of self along with a boolean + /// indicating whether the shift value was larger than or equal to the + /// number of bits. If the shift value is too large, then value is + /// masked (N-1) where N is the number of bits, and this value is then + /// used to perform the shift. + /// + /// # Examples + /// + /// Basic usage + /// + /// ``` + /// #![feature(wrapping)] + /// + /// assert_eq!(0x10u32.overflowing_shr(4), (0x1, false)); + /// assert_eq!(0x10u32.overflowing_shr(36), (0x1, true)); + /// ``` + #[inline] + #[unstable(feature = "wrapping", issue = "27755")] + pub fn overflowing_shr(self, rhs: u32) -> (Self, bool) { + (self >> (rhs & ($BITS - 1)), (rhs > ($BITS - 1))) + } + /// Raises self to the power of `exp`, using exponentiation by squaring. /// /// # Examples