Skip to content

Commit 0473275

Browse files
bors[bot]strakecuviper
committed
Merge #16
16: Define ceiled division, rounding to nearest multiple r=cuviper a=strake I often find `round_up_to` in particular useful; `round_down_to` is also defined for completeness. `div_ceil` is also defined as `round_up_to` is defined in terms of it. Co-authored-by: M Farkas-Dyck <strake888@gmail.com> Co-authored-by: Josh Stone <cuviper@gmail.com>
2 parents f2423e9 + 31ff090 commit 0473275

1 file changed

Lines changed: 105 additions & 0 deletions

File tree

src/lib.rs

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,31 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
7272
/// ~~~
7373
fn mod_floor(&self, other: &Self) -> Self;
7474

75+
/// Ceiled integer division.
76+
///
77+
/// # Examples
78+
///
79+
/// ~~~
80+
/// # use num_integer::Integer;
81+
/// assert_eq!(( 8).div_ceil( &3), 3);
82+
/// assert_eq!(( 8).div_ceil(&-3), -2);
83+
/// assert_eq!((-8).div_ceil( &3), -2);
84+
/// assert_eq!((-8).div_ceil(&-3), 3);
85+
///
86+
/// assert_eq!(( 1).div_ceil( &2), 1);
87+
/// assert_eq!(( 1).div_ceil(&-2), 0);
88+
/// assert_eq!((-1).div_ceil( &2), 0);
89+
/// assert_eq!((-1).div_ceil(&-2), 1);
90+
/// ~~~
91+
fn div_ceil(&self, other: &Self) -> Self {
92+
let (q, r) = self.div_mod_floor(other);
93+
if r.is_zero() {
94+
q
95+
} else {
96+
q + Self::one()
97+
}
98+
}
99+
75100
/// Greatest Common Divisor (GCD).
76101
///
77102
/// # Examples
@@ -171,6 +196,66 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
171196
fn div_mod_floor(&self, other: &Self) -> (Self, Self) {
172197
(self.div_floor(other), self.mod_floor(other))
173198
}
199+
200+
/// Rounds up to nearest multiple of argument.
201+
///
202+
/// # Notes
203+
///
204+
/// For signed types, `a.next_multiple_of(b) = a.prev_multiple_of(b.neg())`.
205+
///
206+
/// # Examples
207+
///
208+
/// ~~~
209+
/// # use num_integer::Integer;
210+
/// assert_eq!(( 16).next_multiple_of(& 8), 16);
211+
/// assert_eq!(( 23).next_multiple_of(& 8), 24);
212+
/// assert_eq!(( 16).next_multiple_of(&-8), 16);
213+
/// assert_eq!(( 23).next_multiple_of(&-8), 16);
214+
/// assert_eq!((-16).next_multiple_of(& 8), -16);
215+
/// assert_eq!((-23).next_multiple_of(& 8), -16);
216+
/// assert_eq!((-16).next_multiple_of(&-8), -16);
217+
/// assert_eq!((-23).next_multiple_of(&-8), -24);
218+
/// ~~~
219+
#[inline]
220+
fn next_multiple_of(&self, other: &Self) -> Self
221+
where
222+
Self: Clone,
223+
{
224+
let m = self.mod_floor(other);
225+
self.clone()
226+
+ if m.is_zero() {
227+
Self::zero()
228+
} else {
229+
other.clone() - m
230+
}
231+
}
232+
233+
/// Rounds down to nearest multiple of argument.
234+
///
235+
/// # Notes
236+
///
237+
/// For signed types, `a.prev_multiple_of(b) = a.next_multiple_of(b.neg())`.
238+
///
239+
/// # Examples
240+
///
241+
/// ~~~
242+
/// # use num_integer::Integer;
243+
/// assert_eq!(( 16).prev_multiple_of(& 8), 16);
244+
/// assert_eq!(( 23).prev_multiple_of(& 8), 16);
245+
/// assert_eq!(( 16).prev_multiple_of(&-8), 16);
246+
/// assert_eq!(( 23).prev_multiple_of(&-8), 24);
247+
/// assert_eq!((-16).prev_multiple_of(& 8), -16);
248+
/// assert_eq!((-23).prev_multiple_of(& 8), -24);
249+
/// assert_eq!((-16).prev_multiple_of(&-8), -16);
250+
/// assert_eq!((-23).prev_multiple_of(&-8), -16);
251+
/// ~~~
252+
#[inline]
253+
fn prev_multiple_of(&self, other: &Self) -> Self
254+
where
255+
Self: Clone,
256+
{
257+
self.clone() - self.mod_floor(other)
258+
}
174259
}
175260

176261
/// Simultaneous integer division and modulus
@@ -193,6 +278,11 @@ pub fn mod_floor<T: Integer>(x: T, y: T) -> T {
193278
pub fn div_mod_floor<T: Integer>(x: T, y: T) -> (T, T) {
194279
x.div_mod_floor(&y)
195280
}
281+
/// Ceiled integer division
282+
#[inline]
283+
pub fn div_ceil<T: Integer>(x: T, y: T) -> T {
284+
x.div_ceil(&y)
285+
}
196286

197287
/// Calculates the Greatest Common Divisor (GCD) of the number and `other`. The
198288
/// result is always positive.
@@ -248,6 +338,16 @@ macro_rules! impl_integer_for_isize {
248338
}
249339
}
250340

341+
#[inline]
342+
fn div_ceil(&self, other: &Self) -> Self {
343+
let (d, r) = self.div_rem(other);
344+
if (r > 0 && *other > 0) || (r < 0 && *other < 0) {
345+
d + 1
346+
} else {
347+
d
348+
}
349+
}
350+
251351
/// Calculates the Greatest Common Divisor (GCD) of the number and
252352
/// `other`. The result is always positive.
253353
#[inline]
@@ -540,6 +640,11 @@ macro_rules! impl_integer_for_usize {
540640
*self % *other
541641
}
542642

643+
#[inline]
644+
fn div_ceil(&self, other: &Self) -> Self {
645+
*self / *other + (0 != *self % *other) as Self
646+
}
647+
543648
/// Calculates the Greatest Common Divisor (GCD) of the number and `other`
544649
#[inline]
545650
fn gcd(&self, other: &Self) -> Self {

0 commit comments

Comments
 (0)