File tree 1 file changed +16
-4
lines changed
1 file changed +16
-4
lines changed Original file line number Diff line number Diff line change @@ -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
}
You can’t perform that action at this time.
0 commit comments