Skip to content

Commit e3dcbd3

Browse files
committed
Pull floored division algorithm from stdlib
1 parent 7949d2c commit e3dcbd3

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

time/src/internal_macros.rs

+20-11
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,27 @@ macro_rules! impl_div_assign {
5151

5252
/// Division of integers, rounding the resulting value towards negative infinity.
5353
macro_rules! div_floor {
54-
($a:expr, $b:expr) => {{
55-
let _a = $a;
56-
let _b = $b;
57-
58-
let (_quotient, _remainder) = (_a / _b, _a % _b);
59-
60-
if (_remainder > 0 && _b < 0) || (_remainder < 0 && _b > 0) {
61-
_quotient - 1
62-
} else {
63-
_quotient
54+
($self:expr, $rhs:expr) => {
55+
match ($self, $rhs) {
56+
(this, rhs) => {
57+
let d = this / rhs;
58+
let r = this % rhs;
59+
60+
// If the remainder is non-zero, we need to subtract one if the
61+
// signs of self and rhs differ, as this means we rounded upwards
62+
// instead of downwards. We do this branchlessly by creating a mask
63+
// which is all-ones iff the signs differ, and 0 otherwise. Then by
64+
// adding this mask (which corresponds to the signed value -1), we
65+
// get our correction.
66+
let correction = (this ^ rhs) >> (::core::mem::size_of_val(&this) * 8 - 1);
67+
if r != 0 {
68+
d + correction
69+
} else {
70+
d
71+
}
72+
}
6473
}
65-
}};
74+
};
6675
}
6776

6877
/// Cascade an out-of-bounds value.

0 commit comments

Comments
 (0)