-1

I'm just experimenting with bitfields in C(beginner). Let's say I have an integer:

uint8 myBitfield

How do I check that all bits except the Least Significant Bit are set.

I thought this shall work:

if ((myBitfield & 0xFE) == 1)   // 0xFE = 0b11111110
{
/*yes all bits except the Least Significant is set*/
}

Any proposal?

JohnDoe
  • 825
  • 1
  • 13
  • 31
  • Hint: try an example of a bitfield that should pass this, and see what you actually get when you AND with 0xFE. You won't get 1... – Nate Eldredge Dec 03 '19 at 12:11
  • 1
    The if instruction should be `if ((myBitfield & 0xFE) == 0xFE)`. You were not that far. Note that the last bit may be 0 or 1 with the test. Is that what you wanted ? – chmike Dec 03 '19 at 12:28
  • if (myBitField == 0xFE) {} ensures that all bits except the LSB are set. It is a bit doubtful that's what you actually meant. – Hans Passant Dec 03 '19 at 13:07

2 Answers2

1

The code you wrote won't check what you expect

if ((myBitfield & 0xFE) == 1)   // 0xFE = 0b11111110
{
/*yes all bits except the Least Significant is set*/
}

More than that, the code inside the if block will never be executed because you clear the least significant bit (LSB) of myBitfield by the & 0xFE operation.

What you are looking for can be implemented by:

if (myBitfield == (uint8_t)~1)   // (uint8_t)~1 = 0b11111110
{
/*yes all bits except the Least Significant is set*/
}

Note that this is not the only way to implement such check. For example, it can also be written as

if (myBitfield == 0xFE)

or

if ((uint8_t)(myBitfield + 2) == 0)  // 0b1111110 + 0b00000010 = 0b1_00000000

and so on...

EDIT

If you meant that you want to check that bit 1 to 7 are set while bit 0 can be anything, you can then "force" this bit (bit 0) to be 0 and compare the result to the mask of all bits set from bit 1 to bit 7 (which is 0xFE):

if ( (myBitfield & 0xFE) == 0xFE)

Of course you also can check against all possible options without applying bitwise operations but the bitwise check looks better, in my opinion, and it also introduces better performance because it has a single branch while the example below contains 2 branches:

if (myBitfield == 0xFE || myBitfield == 0xFF)
Alex Lop.
  • 6,810
  • 1
  • 26
  • 45
  • 1
    This does not test whether all bits except the least significant bit are set. It tests whether all bits except the least significant are set and the least significant bit is zero. – Eric Postpischil Dec 03 '19 at 12:45
  • @EricPostpischil Correct me if I am wrong but "How do I check that all bits except the Least Significant Bit are set." means that all bits are expected to be set except the least significant (which, as I understand, is not set). – Alex Lop. Dec 03 '19 at 12:50
  • The phrase excepts the least significant bit and states no requirements for it. Humans are imprecise and error prone, so the speaker could have intended the other meaning. However, if they had wanted to test whether the high seven bits were set and the lowest was not, they are asking to test that the bits are 11111110, and the obvious test is `myBitfield = 0xFE`. The fact that they attempted `myBitfield & 0xFE` is a further clue that they were attempting to consider the high seven bits separately and to neglect the low bit. – Eric Postpischil Dec 03 '19 at 13:48
0

Let's have.

uint8 myBitfield2 = myBitfield;

<1> Shift the myBitfield 1 place to the right.

myBitfield2 = myBitfield2 >> 1;

This will cause the myBitfield2 to shift right and evict the least significant bit.

<2> Or 0x80 [0b1000000] with the myBitfield2.

This will insert a 1 in the most significant place of the myBitfield2.

<3> Find Complement of the myBitfield by performing myBitfield = 0xFF - myBitfield.

Check if the complement is 0 then the original bitfield had all the bits 1 except the lsb. The lsb could be anything.


int bitField = 0xFF;
int bitField2 = bitField >> 1;
bitField2 = bitField2 | 0x80;
if(0xFF-bitField2==0){
    //All bits except the lsb is 1
}
rsonx
  • 436
  • 7
  • 16