帐前卒专栏

Without software, we are nothing.

Get Absolute Value(integer)

How to get absolute (integer) only use bit operators and +-*/.(In gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)  )

  • if number >= 0 , then number >> 31 == 0
  • if number < 0   , then number >> 31 == 0xFFFFFFFF

If some number exclusive or( xor ) 0xFFFFFFFF means each bit becomes its “opposite” number. (1 becomes 0, and 0 becomes 1).And If a number xor 0x00000000 means nothing happened to this number. So:

  • number ^ 0xFFFFFFFF = ~number
  • number ^ 0x00000000 = number

In this question, you should also know something about complement number(see two’s complement). When a number is negative, |number| = ~number +1 or you can use |number| = !number + 1. When a number is positive, |number| = number.

If you know above, then the goal of |x| = (x(x>>31))+(~(x>>31)+1).

(x(x>>31)) means:

  • x >= 0, x^(x>>31) = x^0x00000000 = x
  • x < 0, x^(x>>31) = x^0xFFFFFFFF = ~x

And (~(x>>31)+1)means:

  • x >= 0, ~(x>>31)+1 = 0xFFFFFFFF+1 = 0
  • x < 0, ~(x>>31)+1 = 0x00000000+1 = 1

And we should take care of those brackets, because the priorities of operators are: ~ > */ > + - > bit operators(&,,|)

Level Operator Description Grouping
1 :: scope Left-to-right
2 () [] . -> ++ – dynamic_cast static_cast reinterpret_cast const_cast typeid postfix Left-to-right
3 ++ – ~ ! sizeof new delete unary (prefix) Right-to-left
* & indirection and reference (pointers)
+ - unary sign operator
4 (type) type casting Right-to-left
5 .* ->* pointer-to-member Left-to-right
6 * / % multiplicative Left-to-right
7 + - additive Left-to-right
8 << >> shift Left-to-right
9 < > <= >= relational Left-to-right
10 == != equality Left-to-right
11 & bitwise AND Left-to-right
12 ^ bitwise XOR Left-to-right
13 | bitwise OR Left-to-right
14 && logical AND Left-to-right
15 || logical OR Left-to-right
16 ?: conditional Right-to-left
17 = *= /= %= += -= >>= <<= &= ^= |= assignment Right-to-left
18 , comma Left-to-right

Comments