# Checking if a bit is set, when it's not the first

This topic is 1155 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

00010101

And I wanted to check if the third bit, the one between the other 2 positive ones is positive, should I do a shift to the right, so it becomes the right most 1 bit, then do a shift to the left, so it becomes the left most 1 bit? Then shift, AGAIN, so it goes back to its original position, so i can use & on it?

>> 00000101

<< 10000000

>> 00000100

What im actually asking is: when the bit you want to check, is between other bits, should I handle it this way?

Edited by noatom

##### Share on other sites
bool is_set(uint x, uint bit)
{
return ((x >> bit) & 0x01);
}


Think thats right

Yeah, that makes a hell of a lot more sense than my logic. Thank you

##### Share on other sites

Alternatively:

return x & (1 << bit);


Which works by masking everything but that bit and checking if the result is nonzero.

I always explicitly compare such expressions against 0 to denote it's a test result rather than a numeric answer:

return (x & (1 << bit)) != 0;

##### Share on other sites

Alternatively:

return x & (1 << bit);

Which works by masking everything but that bit and checking if the result is nonzero.

Be careful with the exact types involved. If x is a 64-bit type and you have 32-bit ints, checking bit 40 won't work well with that code, but it'll be fine with the `(x >> bit) & 1' version.
EDIT: Even if x is an unsigned 32-bit integer, I believe checking bit 31 with that code was technically undefined behavior (because of overflow) until C++14.

I've been stung by that 64-bit bug before...
Upgraded a bunch of types from uint32's to uint64's to pack more fields into my masks, and suddenly half my bitmasks stop working needed (1ULL << index), (((uint64)1) << index), etc, instead of (1 << index).

On the same topic as edit - right shift is also bullshit (aka "implementation defined") in C++ too. Although I've never used a compiler that doesn't treat right-shift of a signed variable to be arithmetic/sign-extending, and a right-shift of an unsigned variable to be logical/zero-fill.

##### Share on other sites

On the same topic as edit - right shift is also bullshit (aka "implementation defined") in C++ too. Although I've never used a compiler that doesn't treat right-shift of a signed variable to be arithmetic/sign-extending, and a right-shift of an unsigned variable to be logical/zero-fill.

I have develop two habits that save me a lot of grief:
(1) always use unsigned integer types when doing bitwise manipulations (all these operations are well defined for unsigned types), and
(2) always use literals of the correct type (so 1u if it's an unsigned int, 1ull if it's an unsigned long long, 1.0 if it's a double, etc.).

##### Share on other sites

BTW for masks and Booleans at work we just define a bit-field structure, with an int cast operator if we really need an integer mask.

Edited by imoogiBG

1. 1
2. 2
Rutin
21
3. 3
A4L
15
4. 4
5. 5

• 13
• 26
• 10
• 11
• 44
• ### Forum Statistics

• Total Topics
633742
• Total Posts
3013630
×