Skip to content

Commit 71a3fe8

Browse files
committed
Add rem_floor and rem_ceil
1 parent 1bcbb7c commit 71a3fe8

File tree

2 files changed

+146
-1
lines changed

2 files changed

+146
-1
lines changed

library/core/src/num/int_macros.rs

+81
Original file line numberDiff line numberDiff line change
@@ -2269,6 +2269,45 @@ macro_rules! int_impl {
22692269
}
22702270
}
22712271

2272+
/// Calculates the remainder of `self / rhs` if the quotient is rounded toward negative infinity.
2273+
///
2274+
/// # Panics
2275+
///
2276+
/// This function will panic if `rhs` is zero.
2277+
///
2278+
/// ## Overflow behavior
2279+
///
2280+
/// On overflow, this function will panic if overflow checks are enabled (default in debug
2281+
/// mode) and wrap if overflow checks are disabled (default in release mode).
2282+
///
2283+
/// # Examples
2284+
///
2285+
/// Basic usage:
2286+
///
2287+
/// ```
2288+
/// #![feature(int_roundings)]
2289+
#[doc = concat!("let a: ", stringify!($SelfT)," = 8;")]
2290+
/// let b = 3;
2291+
///
2292+
/// assert_eq!(a.rem_floor(b), 2);
2293+
/// assert_eq!(a.rem_floor(-b), -1);
2294+
/// assert_eq!((-a).rem_floor(b), 1);
2295+
/// assert_eq!((-a).rem_floor(-b), -2);
2296+
/// ```
2297+
#[unstable(feature = "int_roundings", issue = "88581")]
2298+
#[must_use = "this returns the result of the operation, \
2299+
without modifying the original"]
2300+
#[inline]
2301+
#[rustc_inherit_overflow_checks]
2302+
pub const fn rem_floor(self, rhs: Self) -> Self {
2303+
let r = self % rhs;
2304+
if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
2305+
r + rhs
2306+
} else {
2307+
r
2308+
}
2309+
}
2310+
22722311
/// Calculates the quotient of `self` and `rhs`, rounding the result towards positive infinity.
22732312
///
22742313
/// # Panics
@@ -2309,6 +2348,48 @@ macro_rules! int_impl {
23092348
}
23102349
}
23112350

2351+
/// Calculates the remainder of `self / rhs` if the quotient is rounded towards positive infinity.
2352+
///
2353+
/// This operation is *only* available for signed integers,
2354+
/// since the result would be negative if both operands are positive.
2355+
///
2356+
/// # Panics
2357+
///
2358+
/// This function will panic if `rhs` is zero.
2359+
///
2360+
/// ## Overflow behavior
2361+
///
2362+
/// On overflow, this function will panic if overflow checks are enabled (default in debug
2363+
/// mode) and wrap if overflow checks are disabled (default in release mode).
2364+
///
2365+
/// # Examples
2366+
///
2367+
/// Basic usage:
2368+
///
2369+
/// ```
2370+
/// #![feature(rem_ceil)]
2371+
#[doc = concat!("let a: ", stringify!($SelfT)," = 8;")]
2372+
/// let b = 3;
2373+
///
2374+
/// assert_eq!(a.rem_ceil(b), -1);
2375+
/// assert_eq!(a.rem_ceil(-b), 2);
2376+
/// assert_eq!((-a).rem_ceil(b), -2);
2377+
/// assert_eq!((-a).rem_ceil(-b), 1);
2378+
/// ```
2379+
#[unstable(feature = "rem_ceil", issue = "88581")]
2380+
#[must_use = "this returns the result of the operation, \
2381+
without modifying the original"]
2382+
#[inline]
2383+
#[rustc_inherit_overflow_checks]
2384+
pub const fn rem_ceil(self, rhs: Self) -> Self {
2385+
let r = self % rhs;
2386+
if (r > 0 && rhs > 0) || (r < 0 && rhs < 0) {
2387+
r - rhs
2388+
} else {
2389+
r
2390+
}
2391+
}
2392+
23122393
/// If `rhs` is positive, calculates the smallest value greater than or
23132394
/// equal to `self` that is a multiple of `rhs`. If `rhs` is negative,
23142395
/// calculates the largest value less than or equal to `self` that is a

library/core/src/num/uint_macros.rs

+65-1
Original file line numberDiff line numberDiff line change
@@ -2123,6 +2123,32 @@ macro_rules! uint_impl {
21232123
self / rhs
21242124
}
21252125

2126+
/// Calculates the remainder of `self / rhs` if the quotient is rounded toward negative infinity.
2127+
///
2128+
/// This is the same as performing `self % rhs` for all unsigned integers.
2129+
///
2130+
/// # Panics
2131+
///
2132+
/// This function will panic if `rhs` is zero.
2133+
///
2134+
/// # Examples
2135+
///
2136+
/// Basic usage:
2137+
///
2138+
/// ```
2139+
/// #![feature(int_roundings)]
2140+
#[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".rem_floor(4), 3);")]
2141+
/// ```
2142+
#[unstable(feature = "int_roundings", issue = "88581")]
2143+
#[must_use = "this returns the result of the operation, \
2144+
without modifying the original"]
2145+
#[inline]
2146+
#[rustc_inherit_overflow_checks]
2147+
pub const fn rem_floor(self, rhs: Self) -> Self {
2148+
self % rhs
2149+
}
2150+
2151+
21262152
/// Calculates the quotient of `self` and `rhs`, rounding the result towards positive infinity.
21272153
///
21282154
/// # Panics
@@ -2150,13 +2176,51 @@ macro_rules! uint_impl {
21502176
pub const fn div_ceil(self, rhs: Self) -> Self {
21512177
let d = self / rhs;
21522178
let r = self % rhs;
2153-
if r > 0 && rhs > 0 {
2179+
if r != 0 {
21542180
d + 1
21552181
} else {
21562182
d
21572183
}
21582184
}
21592185

2186+
/// Calculates the remainder of `self / rhs` if the quotient is rounded towards positive infinity.
2187+
///
2188+
/// Since this remainder can never be positive, we return the opposite of the actual remainder.
2189+
/// If you want the sign to reflect the actual remainder, you need to use the [signed version].
2190+
///
2191+
#[doc = concat!("[signed version]: primitive.", stringify!($SignedT), ".html#method.rem_ceil")]
2192+
///
2193+
/// # Panics
2194+
///
2195+
/// This function will panic if `rhs` is zero.
2196+
///
2197+
/// ## Overflow behavior
2198+
///
2199+
/// On overflow, this function will panic if overflow checks are enabled (default in debug
2200+
/// mode) and wrap if overflow checks are disabled (default in release mode).
2201+
///
2202+
/// # Examples
2203+
///
2204+
/// Basic usage:
2205+
///
2206+
/// ```
2207+
/// #![feature(rem_ceil)]
2208+
#[doc = concat!("assert_eq!(7_", stringify!($SelfT), ".unsigned_rem_ceil(4), 1);")]
2209+
/// ```
2210+
#[unstable(feature = "rem_ceil", issue = "88581")]
2211+
#[must_use = "this returns the result of the operation, \
2212+
without modifying the original"]
2213+
#[inline]
2214+
#[rustc_inherit_overflow_checks]
2215+
pub const fn unsigned_rem_ceil(self, rhs: Self) -> Self {
2216+
let r = self % rhs;
2217+
if r != 0 {
2218+
rhs - r
2219+
} else {
2220+
r
2221+
}
2222+
}
2223+
21602224
/// Calculates the smallest value greater than or equal to `self` that
21612225
/// is a multiple of `rhs`.
21622226
///

0 commit comments

Comments
 (0)