0
$\begingroup$

solution:

int iabs(int a) {
   int t = a >> 31;
   a = (a^t) - t;
   return a;
}

Can someone explain at the math level why shifting 31 bits to the right, xoring this result with t and subtracting t from this work?

$\endgroup$
1
$\begingroup$

This is more of a programming question than a math one. Note that the right shift >> is sign-extending in the C language. Then, assuming an int is 32-bit wide:

                   // if a >= 0          // if a < 0

int t = a >> 31;   // t = 0              // t = 0xFFFFFFFF = -1
a = (a^t) - t;     // a = (a^0)-0 = a    // a = (a^(-1))-(-1) = ~a + 1 = -a


[ EDIT ]  Strictly speaking, the right-shift behavior is implementation defined in both C and C++, though (emphasis mine):

For negative a, the value of a >> b is implementation-defined (in most implementations, this performs arithmetic right shift, so that the result remains negative).

This is, however, a matter better suited to discuss next door at stackoverflow.com.

$\endgroup$
  • $\begingroup$ So if we have a = -2 = 110 then 110>> 2 = 001 , 110 xor 001 = 111 and 7 - 1 != 2. Why did I do wrong. I think it has something to do with your sign extending claim. $\endgroup$ – ElChavoDelOcho Dec 14 '17 at 1:15
  • $\begingroup$ @Dan It does. Assuming a 3-bit int as you have here, 0x110 >> 2 produces 0x111. It’s an arithmetic shift, not a logical shift. $\endgroup$ – amd Dec 14 '17 at 1:21
  • $\begingroup$ @Dan In a 3-bit two's-complement representation 110 >> 1 = 111 under most implementations (see the edit at the end). In 32-bit -2 = 1111 1111 1111 1110 and -2 >> 31 = 1111 1111 1111 1111. $\endgroup$ – dxiv Dec 14 '17 at 1:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.