Hi, I recently came across a code which had the below lines.
unsigned int n = 10;
n ^= (unsigned int) - 1 ;
It is not clear to me what the second line does.
Anyone can help please :)
Hi, I recently came across a code which had the below lines.
unsigned int n = 10;
n ^= (unsigned int) - 1 ;
It is not clear to me what the second line does.
Anyone can help please :)
n is XOR'ed with an unsigned -1, the resulting value is stored in 'n'
-1 is treated as an unsigned integer, meaning just that it's a variable with all bits are ones. a 32-bit int, will be 0xFFFFFFFF
basically this is like a microcontroller register operation that "flips" all the bits in a register.
i.e., the value 0xA5A5A5A5 when XORed with 0xFFFFFFFF becomes 0x5A5A5A5A
the more i look at it though, the more i'm wondering if it's not an incorrectly rendered attempt to make a negative number using 2's complement arithmetic.
because if it were written ( n ^= (unsigned) -1 ) - 1
(note parentheses) this would be the right hand side (RHS) of an equation that takes the value 'n', inverts it by XORing with 0xFFFFFFFF, then subtracts one ... which gives you the 2's complement binary representation of the original value 'n' made negative. (of course, you'd still have to assign that RHS result to a variable on the LHS for it to be a valid assignment)
so for your example, you have n= 10 which is 0x0000000A
XOR that with 0xFFFFFFFF
gives the result 0xFFFFFFF5
which can either be seen as decimal 4294967285 (unsigned) or -11 (signed). Note that in traditional microprocessor arithmetic, you use registers that dont specify signed or unsigned, it's up to the programmer to interpret it and use it correctly
finally, remember that 2's complement requires you first invert the bits, then subtract one.
so 0xFFFFFFF5 minus 0x00000001 = 0xFFFFFFF4
which is the 2's complement value for -10
.
Nice explanation. But the writer of the original article where I found this code, just wanted to flip the bits.
Here is that code: It counts the number of set bits in a number.
int bitcount (unsigned int n) {
int count = 8 * sizeof(int) ;
n ^= (unsigned int) - 1 ;
while (n) {
count-- ;
n &= (n - 1) ;
}
return count ;
}
okay then, my first post was correct. that is indeed what he's doing: flipping the bits.
notice the (unsigned int) - 1
.... the value of this is an "unsigned -1", aka 0xFFFFFFFF, but it's confusing because he has a space between the negative sign and the one. ie, "- 1"
instead of "-1"
.
this is not technically incorrect because the compiler ignores the whitespace in this case, but it makes for a confusing read because it makes you think of a subtraction operation -- which it is not. i believe that whitespace is an unintended typo that happened to not get noticed because it didn't affect the program execution.
its why i thought maybe it was a flawed attempt of 2's complement negation, and probably why it was confusing to you also.
.