Why shift operation below works and end up equal? Is there any name for this pattern? I am trying to find out what was going on in the head of the person who wrote this code!
int i = 0x1;
i |= 0x1 << 1;
i |= 0x1 << 2;
i |= 0x1 << 3;
i |= 0x1 << 4;
i |= 0x1 << 5;
int j = 5;
if( ((0x1 << (j + 1)) - 1) == i)
{
// WHY?
}
I tried to check if this is true for all numbers but only works up to 31.
for (int i = 1; i <= 100; i++) {
int total_1 = 0x1;
for (int j = 1; j <= i; j++) {
total_1 |= 0x1 << j;
}
int total_2 = (0x1 << (i + 1)) - 1;
if (total_2 == total_1) {
} else {
cout << i << endl;
break;
}
}
UPDATE
Please explain the first part why they would end up equal?
Is there any name for this pattern?
0x1u << pos
(or just 1u << pos
) is a pattern for getting a number with only the bit in position pos
is set. Using signed 0x1
is usually an anti-pattern.
i |= 1u << pos
is a pattern for setting a bit in position pos
of the integer i
.
(1u << pos) - 1
is a pattern for creating a pattern of set bits only in positions lesser than pos
.
Why shift operation below works and end up equal?
Perhaps it may help to look at intermediate results:
// least significant byte
int i = 0x1; // 0b0000'0001
i |= 0x1 << 1; // 0b0000'0011
i |= 0x1 << 2; // 0b0000'0111
i |= 0x1 << 3; // 0b0000'1111
i |= 0x1 << 4; // 0b0001'1111
i |= 0x1 << 5; // 0b0011'1111
int j = 5;
0x1 << (j + 1)
0x1 << 6 // 0b0100'0000
(0x1 << (j + 1)) - 1
0b0100'0000 - 1 // 0b0011'1111
only works up to 31
int
is probably 32 bits wide on your system. If you left shift a 32 bit 0x1 by 31 or greater, then the behaviour of the program is undefined. If you were to use 0x1u
, then you could shift by 31, but 32 and above would be UB.