diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index fa37ee4ffb204..630cd69b00b0f 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -2825,6 +2825,45 @@ macro_rules! int_impl { } } + /// Calculates the remainder of `self / rhs` if the quotient is rounded toward negative infinity. + /// + /// # Panics + /// + /// This function will panic if `rhs` is zero. + /// + /// ## Overflow behavior + /// + /// On overflow, this function will panic if overflow checks are enabled (default in debug + /// mode) and wrap if overflow checks are disabled (default in release mode). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(int_roundings)] + #[doc = concat!("let a: ", stringify!($SelfT)," = 8;")] + /// let b = 3; + /// + /// assert_eq!(a.rem_floor(b), 2); + /// assert_eq!(a.rem_floor(-b), -1); + /// assert_eq!((-a).rem_floor(b), 1); + /// assert_eq!((-a).rem_floor(-b), -2); + /// ``` + #[unstable(feature = "int_roundings", issue = "88581")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + #[rustc_inherit_overflow_checks] + pub const fn rem_floor(self, rhs: Self) -> Self { + let r = self % rhs; + if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) { + r + rhs + } else { + r + } + } + /// Calculates the quotient of `self` and `rhs`, rounding the result towards positive infinity. /// /// # Panics @@ -2861,6 +2900,48 @@ macro_rules! int_impl { } } + /// Calculates the remainder of `self / rhs` if the quotient is rounded towards positive infinity. + /// + /// This operation is *only* available for signed integers, + /// since the result would be negative if both operands are positive. + /// + /// # Panics + /// + /// This function will panic if `rhs` is zero. + /// + /// ## Overflow behavior + /// + /// On overflow, this function will panic if overflow checks are enabled (default in debug + /// mode) and wrap if overflow checks are disabled (default in release mode). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(rem_ceil)] + #[doc = concat!("let a: ", stringify!($SelfT)," = 8;")] + /// let b = 3; + /// + /// assert_eq!(a.rem_ceil(b), -1); + /// assert_eq!(a.rem_ceil(-b), 2); + /// assert_eq!((-a).rem_ceil(b), -2); + /// assert_eq!((-a).rem_ceil(-b), 1); + /// ``` + #[unstable(feature = "rem_ceil", issue = "88581")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + #[rustc_inherit_overflow_checks] + pub const fn rem_ceil(self, rhs: Self) -> Self { + let r = self % rhs; + if (r > 0 && rhs > 0) || (r < 0 && rhs < 0) { + r - rhs + } else { + r + } + } + /// If `rhs` is positive, calculates the smallest value greater than or /// equal to `self` that is a multiple of `rhs`. If `rhs` is negative, /// calculates the largest value less than or equal to `self` that is a diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f2f29e4ad8194..5df1473bd456f 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2583,6 +2583,32 @@ macro_rules! uint_impl { self / rhs } + /// Calculates the remainder of `self / rhs` if the quotient is rounded toward negative infinity. + /// + /// This is the same as performing `self % rhs` for all unsigned integers. + /// + /// # Panics + /// + /// This function will panic if `rhs` is zero. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(int_roundings)] + #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".rem_floor(4), 3);")] + /// ``` + #[unstable(feature = "int_roundings", issue = "88581")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + #[rustc_inherit_overflow_checks] + pub const fn rem_floor(self, rhs: Self) -> Self { + self % rhs + } + + /// Calculates the quotient of `self` and `rhs`, rounding the result towards positive infinity. /// /// # Panics @@ -2605,13 +2631,51 @@ macro_rules! uint_impl { pub const fn div_ceil(self, rhs: Self) -> Self { let d = self / rhs; let r = self % rhs; - if r > 0 && rhs > 0 { + if r != 0 { d + 1 } else { d } } + /// Calculates the remainder of `self / rhs` if the quotient is rounded towards positive infinity. + /// + /// Since this remainder can never be positive, we return the opposite of the actual remainder. + /// If you want the sign to reflect the actual remainder, you need to use the [signed version]. + /// + #[doc = concat!("[signed version]: primitive.", stringify!($SignedT), ".html#method.rem_ceil")] + /// + /// # Panics + /// + /// This function will panic if `rhs` is zero. + /// + /// ## Overflow behavior + /// + /// On overflow, this function will panic if overflow checks are enabled (default in debug + /// mode) and wrap if overflow checks are disabled (default in release mode). + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(rem_ceil)] + #[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unsigned_rem_ceil(4), 1);")] + /// ``` + #[unstable(feature = "rem_ceil", issue = "88581")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + #[rustc_inherit_overflow_checks] + pub const fn unsigned_rem_ceil(self, rhs: Self) -> Self { + let r = self % rhs; + if r != 0 { + rhs - r + } else { + r + } + } + /// Calculates the smallest value greater than or equal to `self` that /// is a multiple of `rhs`. ///