Absolute value abs(x) using bitwise operators and Boolean logic

beta_me me_beta picture beta_me me_beta · Mar 9, 2020 · Viewed 8.5k times · Source

How does this work?

The idea is to make abs(x) use bitwise operators for integers (assuming 32 bit words):

y = x >> 31
(x + y) ^ y // This gives abs(x) (is ^ XOR)?

Answer

Eric Postpischil picture Eric Postpischil · Mar 9, 2020

Assuming 32-bit words, as stated in the question:

For negative x, x >> 31 is implementation-defined in the C and C++ standards. The author of the code expects two’s complement integers and an arithmetic right-shift, in which x >> 31 produces all zero bits if the sign bit of x is zero and all one bits if the sign bit is one.

Thus, if x is positive or zero, y is zero, and x + y is x, so (x + y) ^ y is x, which is the absolute value of x.

If x is negative, y is all ones, which represents −1 in two’s complement. Then x + y is x - 1. Then XORing with all ones inverts all the bits. Inverting all the bits is equivalent to taking the two’s complement and subtracting one, and two’s complement is the method used to negate integers in two’s complement format. In other words, XORing q with all ones gives -q - 1. So x - 1 XORed with all ones produces -(x - 1) - 1 = -x + 1 - 1 = -x, which is the absolute value of x except when x is the minimum possible value for the format (−2,147,483,648 for 32-bit two’s complement), in which case the absolute value (2,147,483,648) is too large to represent, and the resulting bit pattern is just the original x.