user11954200
user11954200

Reputation:

Manually adding a bitmask vs adding a bitwise shift

I am trying to add in a left-wise operator to replace the following:

unsigned long bitmask = 0b10000000000000000000000000000000;
printf("%lu\n", bitmask);

unsigned long bitmask2 = (1 << 31)-1;
printf("%lu\n", bitmask2);

However, the closest I'm able to get is -1. If I try doing (1 << 31), it looks like I get an overflow or something. What would be the proper way to do this?

# in the python shell
>>> 0b10000000000000000000000000000000
2147483648

>>> 1<<31
2147483648

>>> 0b10000000000000000000000000000000 == 1<<31
True

Upvotes: 2

Views: 1435

Answers (3)

Adrian Shum
Adrian Shum

Reputation: 40036

Change

unsigned long bitmask2 = (1 << 31)-1;

to something like

unsigned long bitmask2 = (1UL << 31);

instead

The overflow was caused by you are bitwise shifting 31 places for 1 which exceed the boundary of a signed int. Please note that 1 is a signed int literal.

Upvotes: 1

Lundin
Lundin

Reputation: 213368

All integer constants like 1 have a type, in this case int. An int is signed and therefore has 31 data bits and 1 sign bit. You cannot left shift data into this sign bit - 1<<31 is a severe undefined behavior bug.

As a rule of thumb, never mix signed operands with bitwise operators. You can fix the bug by adding a 'u' suffix to the integer constant: 1u << 31. Now the type is unsigned int instead, 32 data bits.

Please note that the resulting type of a shift operation is that of the left operand. So there is no need to write for example 1u << 31u.

Upvotes: 0

1201ProgramAlarm
1201ProgramAlarm

Reputation: 32732

Since the type of the result of your shift is unsigned long, you should start with an unsigned long constant:

unsigned long bitmask2 = (1UL << 31) - 1;

Upvotes: 3

Related Questions