@@ -1402,7 +1402,16 @@ $EndFeature, "
1402
1402
#[ stable( feature = "no_panic_abs" , since = "1.13.0" ) ]
1403
1403
#[ inline]
1404
1404
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)
1406
1415
}
1407
1416
}
1408
1417
@@ -1761,7 +1770,7 @@ $EndFeature, "
1761
1770
#[ stable( feature = "no_panic_abs" , since = "1.13.0" ) ]
1762
1771
#[ inline]
1763
1772
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 ( ) )
1765
1774
}
1766
1775
}
1767
1776
@@ -1969,7 +1978,21 @@ $EndFeature, "
1969
1978
// Note that the #[inline] above means that the overflow
1970
1979
// semantics of the subtraction depend on the crate we're being
1971
1980
// 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
1973
1996
}
1974
1997
}
1975
1998
0 commit comments