Skip to content

Commit 8060100

Browse files
committed
Fix implementation of Duration::checked_div
1 parent a9fea9f commit 8060100

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

tests/duration.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,14 @@ fn checked_div() {
388388
assert_eq!(Duration::MIN.checked_div(-1), None);
389389
}
390390

391+
#[test]
392+
fn checked_div_regression() {
393+
assert_eq!(
394+
Duration::new(1, 1).checked_div(7),
395+
Some(Duration::new(0, 142_857_143)) // manually verified
396+
);
397+
}
398+
391399
#[test]
392400
fn saturating_add() {
393401
assert_eq!(5.seconds().saturating_add(5.seconds()), 10.seconds());

time/src/duration.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -994,16 +994,16 @@ impl Duration {
994994
/// assert_eq!(1.seconds().checked_div(0), None);
995995
/// ```
996996
pub const fn checked_div(self, rhs: i32) -> Option<Self> {
997-
let seconds = const_try_opt!(self.seconds.checked_div(rhs as i64));
998-
let carry = self.seconds - seconds * (rhs as i64);
999-
let extra_nanos =
1000-
const_try_opt!((carry * Nanosecond.per(Second) as i64).checked_div(rhs as i64));
1001-
let nanoseconds =
1002-
const_try_opt!(self.nanoseconds.get().checked_div(rhs)) + (extra_nanos as i32);
1003-
1004-
// Safety: TODO may not be safe? `nanoseconds` could overflow past a billion on final
1005-
// addition?
1006-
unsafe { Some(Self::new_unchecked(seconds, nanoseconds)) }
997+
let (secs, extra_secs) = (
998+
const_try_opt!(self.seconds.checked_div(rhs as i64)),
999+
self.seconds % (rhs as i64),
1000+
);
1001+
let (mut nanos, extra_nanos) = (self.nanoseconds.get() / rhs, self.nanoseconds.get() % rhs);
1002+
nanos += ((extra_secs * (Nanosecond.per(Second) as i64) + extra_nanos as i64)
1003+
/ (rhs as i64)) as i32;
1004+
1005+
// Safety: `nanoseconds` is in range.
1006+
unsafe { Some(Self::new_unchecked(secs, nanos)) }
10071007
}
10081008
// endregion checked arithmetic
10091009

0 commit comments

Comments
 (0)