Skip to content

Commit

Permalink
Add rem_floor and rem_ceil
Browse files Browse the repository at this point in the history
  • Loading branch information
clarfonthey committed Nov 18, 2023
1 parent 547ace8 commit 95a4369
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 1 deletion.
81 changes: 81 additions & 0 deletions library/core/src/num/int_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2269,6 +2269,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
Expand Down Expand Up @@ -2309,6 +2348,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
Expand Down
66 changes: 65 additions & 1 deletion library/core/src/num/uint_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2123,6 +2123,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
Expand Down Expand Up @@ -2150,13 +2176,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`.
///
Expand Down

0 comments on commit 95a4369

Please sign in to comment.