Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why this shift operation plus bitwise works only up to 31?

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Please explain the first part why they would end up equal?

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading