Skip to content

Commit cde58ee

Browse files
committed
Fix prev/next_multiple_of(&MIN, &-1)
1 parent d5267dc commit cde58ee

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

src/lib.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,29 @@ macro_rules! impl_integer_for_isize {
563563
fn div_rem(&self, other: &Self) -> (Self, Self) {
564564
(*self / *other, *self % *other)
565565
}
566+
567+
/// Rounds up to nearest multiple of argument.
568+
#[inline]
569+
fn next_multiple_of(&self, other: &Self) -> Self {
570+
// Avoid the overflow of `MIN % -1`
571+
if *other == -1 {
572+
return *self;
573+
}
574+
575+
let m = Integer::mod_floor(self, other);
576+
*self + if m == 0 { 0 } else { other - m }
577+
}
578+
579+
/// Rounds down to nearest multiple of argument.
580+
#[inline]
581+
fn prev_multiple_of(&self, other: &Self) -> Self {
582+
// Avoid the overflow of `MIN % -1`
583+
if *other == -1 {
584+
return *self;
585+
}
586+
587+
*self - Integer::mod_floor(self, other)
588+
}
566589
}
567590

568591
#[cfg(test)]
@@ -785,6 +808,16 @@ macro_rules! impl_integer_for_isize {
785808
assert_eq!((3 as $T).is_odd(), true);
786809
assert_eq!((4 as $T).is_odd(), false);
787810
}
811+
812+
#[test]
813+
fn test_multiple_of_one_limits() {
814+
for x in &[<$T>::min_value(), <$T>::max_value()] {
815+
for one in &[1, -1] {
816+
assert_eq!(Integer::next_multiple_of(x, one), *x);
817+
assert_eq!(Integer::prev_multiple_of(x, one), *x);
818+
}
819+
}
820+
}
788821
}
789822
};
790823
}

0 commit comments

Comments
 (0)