How could I use bit masking to make all the bits in a number 1 if they were all 0, and all 0 if they were not?
Using an unsigned variable:
So, if I have 0000-0000
, I would like that to become 1111-1111
.
If I have 0101-0110
(or 0000-0001
, or 1111-1111
, etc), I would like that to become 0000-0000
.
Is this possible to do without using any conditional?
Sure, it's possible:
int y = 0xff;
y = ~(y & 1 | y>>1 & 1 | y>>2 & 1 | ...) - 1
But unless this is an academic exercise, you really shouldn't. If you're concerned about performance, y = y != 0
is almost certainly faster.
Explanation:
y & 1
takes the first bit of the number. y >> k
shifts the number right by k
bits, allowing us to get that bit by y >> k & 1
. We simply |
them together, which results in one if any bit is set or zero if not. Subtracting 1 gives us 0 if any bit was set, and -1 if not. The binary representation of -1 is 1111...
Shift:
1010 - y
1010 - y >> 0
101 - y >> 1
10 - y >> 2
1 - y >> 3
Take the first bit:
0 - y >> 0 & 1
1 - y >> 1 & 1
0 - y >> 3 & 1
1 - y >> 4 & 1
Or them:
1 - 0 | 1 | 0 | 1
Negate:
0000 - 1-1