better implementation of signed div_floor/ceil · qinheping/verify-rust-std@b947f0a (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

`}

`