Auto merge of #130002 - orlp:better-div-floor-ceil, r=thomcc · qinheping/verify-rust-std@4caabcd (original) (raw)
`@@ -3023,8 +3023,16 @@ macro_rules! int_impl {
`
3023
3023
`pub const fn div_floor(self, rhs: Self) -> Self {
`
3024
3024
`let d = self / rhs;
`
3025
3025
`let r = self % rhs;
`
3026
``
`-
if (r > 0 && rhs < 0) || (r < 0 && rhs > 0) {
`
3027
``
`-
d - 1
`
``
3026
+
``
3027
`+
// If the remainder is non-zero, we need to subtract one if the
`
``
3028
`+
// signs of self and rhs differ, as this means we rounded upwards
`
``
3029
`+
// instead of downwards. We do this branchlessly by creating a mask
`
``
3030
`+
// which is all-ones iff the signs differ, and 0 otherwise. Then by
`
``
3031
`+
// adding this mask (which corresponds to the signed value -1), we
`
``
3032
`+
// get our correction.
`
``
3033
`+
let correction = (self ^ rhs) >> (Self::BITS - 1);
`
``
3034
`+
if r != 0 {
`
``
3035
`+
d + correction
`
3028
3036
`} else {
`
3029
3037
` d
`
3030
3038
`}
`
`@@ -3059,8 +3067,12 @@ macro_rules! int_impl {
`
3059
3067
`pub const fn div_ceil(self, rhs: Self) -> Self {
`
3060
3068
`let d = self / rhs;
`
3061
3069
`let r = self % rhs;
`
3062
``
`-
if (r > 0 && rhs > 0) || (r < 0 && rhs < 0) {
`
3063
``
`-
d + 1
`
``
3070
+
``
3071
`+
// When remainder is non-zero we have a.div_ceil(b) == 1 + a.div_floor(b),
`
``
3072
`+
// so we can re-use the algorithm from div_floor, just adding 1.
`
``
3073
`+
let correction = 1 + ((self ^ rhs) >> (Self::BITS - 1));
`
``
3074
`+
if r != 0 {
`
``
3075
`+
d + correction
`
3064
3076
`} else {
`
3065
3077
` d
`
3066
3078
`}
`