@@ -1402,7 +1402,16 @@ $EndFeature, "
14021402 #[ stable( feature = "no_panic_abs" , since = "1.13.0" ) ]
14031403 #[ inline]
14041404 pub const fn wrapping_abs( self ) -> Self {
1405- ( self ^ ( self >> ( $BITS - 1 ) ) ) . wrapping_sub( self >> ( $BITS - 1 ) )
1405+ // sign is -1 (all ones) for negative numbers, 0 otherwise.
1406+ let sign = self >> ( $BITS - 1 ) ;
1407+ // For positive self, sign == 0 so the expression is simply
1408+ // (self ^ 0).wrapping_sub(0) == self == abs(self).
1409+ //
1410+ // For negative self, self ^ sign == self ^ all_ones.
1411+ // But all_ones ^ self == all_ones - self == -1 - self.
1412+ // So for negative numbers, (self ^ sign).wrapping_sub(sign) is
1413+ // (-1 - self).wrapping_sub(-1) == -self == abs(self).
1414+ ( self ^ sign) . wrapping_sub( sign)
14061415 }
14071416 }
14081417
@@ -1761,7 +1770,7 @@ $EndFeature, "
17611770 #[ stable( feature = "no_panic_abs" , since = "1.13.0" ) ]
17621771 #[ inline]
17631772 pub const fn overflowing_abs( self ) -> ( Self , bool ) {
1764- ( self ^ ( self >> ( $BITS - 1 ) ) ) . overflowing_sub ( self >> ( $BITS - 1 ) )
1773+ ( self . wrapping_abs ( ) , self == Self :: min_value ( ) )
17651774 }
17661775 }
17671776
@@ -1969,7 +1978,21 @@ $EndFeature, "
19691978 // Note that the #[inline] above means that the overflow
19701979 // semantics of the subtraction depend on the crate we're being
19711980 // inlined into.
1972- ( self ^ ( self >> ( $BITS - 1 ) ) ) - ( self >> ( $BITS - 1 ) )
1981+
1982+ // sign is -1 (all ones) for negative numbers, 0 otherwise.
1983+ let sign = self >> ( $BITS - 1 ) ;
1984+ // For positive self, sign == 0 so the expression is simply
1985+ // (self ^ 0) - 0 == self == abs(self).
1986+ //
1987+ // For negative self, self ^ sign == self ^ all_ones.
1988+ // But all_ones ^ self == all_ones - self == -1 - self.
1989+ // So for negative numbers, (self ^ sign) - sign is
1990+ // (-1 - self) - -1 == -self == abs(self).
1991+ //
1992+ // The subtraction overflows when self is min_value(), because
1993+ // (-1 - min_value()) - -1 is max_value() - -1 which overflows.
1994+ // This is exactly when we want self.abs() to overflow.
1995+ ( self ^ sign) - sign
19731996 }
19741997 }
19751998
0 commit comments