Search code examples
c++cintegerbitbitwise-and

Using AND bitwise operator between a number, and its negative counterpart


I stumbled upon this simple line of code, and I cannot figure out what it does. I understand what it does in separate parts, but I don't really understand it as a whole.

// We have an integer(32 bit signed) called i
// The following code snippet is inside a for loop declaration
// in place of a simple incrementor like i++ 
// for(;;HERE){}
i += (i&(-i))

If I understand correctly it uses the AND binary operator between i and negative i and then adds that number to i. I first thought that this would be an optimized way of calculating the absolute value of an integer, however as I come to know, c++ does not store negative integers simply by flipping a bit, but please correct me if I'm wrong.


Solution

  • Assuming two's complement representation, and assuming i is not INT_MIN, the expression i & -i results in the value of the lowest bit set in i.

    If we look at the value of this expression for various values of i:

     0 00000000: i&(-i) = 0
     1 00000001: i&(-i) = 1
     2 00000010: i&(-i) = 2
     3 00000011: i&(-i) = 1
     4 00000100: i&(-i) = 4
     5 00000101: i&(-i) = 1
     6 00000110: i&(-i) = 2
     7 00000111: i&(-i) = 1
     8 00001000: i&(-i) = 8
     9 00001001: i&(-i) = 1
    10 00001010: i&(-i) = 2
    11 00001011: i&(-i) = 1
    12 00001100: i&(-i) = 4
    13 00001101: i&(-i) = 1
    14 00001110: i&(-i) = 2
    15 00001111: i&(-i) = 1
    16 00010000: i&(-i) = 16
    

    We can see this pattern.

    Extrapolating that to i += (i&(-i)), assuming i is positive, it adds the value of the lowest set bit to i. For values that are a power of two, this just doubles the number.

    For other values, it rounds the number up by the value of that lowest bit. Repeating this in a loop, you eventually end up with a power of 2. As for what such an increment could be used for, that depends on the context of where this expression was used.