Reputation: 35
In the book I am reading to learn C "The C programming language" in chapter 2.
The book is explaining Bitwise operations and it has a function that shows how many bits are in an integer.
The following is the function...
int Bitcount(unsigned x){
int b;
for(b = 0; x != 0; x >>=1){
if(x & 01){
b++
}
}
return b;
}
Then an exercise is given to us stating exactly this.
"In a two's complement number system, x &= (x-1) deletes the rightmost 1-bit in x;
Explain why. Use this observation to write a faster version of Bitcount".
The problem is I really cannot understand how "x &= (x-1)" would work? can someone explain this to me? or send me to a resource that could better help me understand? I have been trying to figure this out but I really can't.
Thank you for any help that you may give.
also if there is anything wrong with my question this is my first post so please help me make my questions better.
Upvotes: 2
Views: 731
Reputation: 3571
The problem is I really cannot understand how "x &= (x-1)" would work?
Binary number is positional the same way as decimal number. When we increase the number we carry a bit to the left, when we decrease we borrow from the left the same way we do with decimals. So in case x-01
we borrow the first 1-bit from the right while others being set to 1-bit:
10101000
- 00000001
--------
10100111
which is inversion of those bits till the first 1-bit. And as stated before by others ~y & y = 0
that is why this method can be used to count 1-bits as proposed by the book to make the method faster comparing to bits shifting.
Upvotes: 0
Reputation: 32953
X and X-1 cannot both have their rightmost bit set to 1, because in the binary system numbers ending in 0 and 1 alternate - so X & (X-1) is guaranteed to be a number whose rightmost bit set to 0 as AND only evaluates to true if both terms are true. Maybe the confusion stems from what Andrew W said, here a bitwise AND is used (which ANDs each bit individually)?
EDIT: now, as Inspired points out, this is only part of the answer as the original problem specifies that the rightmost 1-bit will get reset. As Andrew W already answered the correct version in detail, I'm not going to repeat his explanation here but I refer to his answer.
Upvotes: 4
Reputation: 4598
It is equivalent to x = x & (x-1)
Here, the & is a bitwise and, not a logical and.
So here's what happens:
1) The expression on the right will be evaluated first, and that value will be stored in x.
2) Suppose x = 01001011
in binary (this isn't the case, since more than 8 bits will be used to represent x, but pretend it is for this example). Then x-1 = 01001010
.
3) compute the bitwise and:
01001011 &
01001010 =
01001010
which deleted the rightmost one bit.
now suppose number didn't end with a 1 bit:
Say: x = 01001100
, the (x-1) = 01001011
compute the bitwise and:
01001100 &
01001011 =
01001000
again removing the rightmost 1.
Good book by the way. I hope you enjoy it!
Upvotes: 3
Reputation: 11058
Let's take a closer look at the rightmost 1 bit in x: suppose x = AAAAAA10000..0
, where AAAAAA are arbitrary bits. Then x-1 = AAAAAA01111..1
. Bitwise AND of these two expressions gives AAAAAA00000..0
. This is how it resets the rightmost non-zero bit.
Upvotes: 0