views:

177

answers:

6

Right now I'm using this to set/unset individual bits in a byte:

if (bit4Set)
   nbyte |= (1 << 4);
else
   nbyte &= ~(1 << 4);

But, can't you do that in a more simple/elegant way? Like setting or unsetting the bit in a single operation?

Note: I understand I can just write a function to do that, I'm just wondering if I won't be reinventing the wheel.

+2  A: 

Sure! It would be more obvious if you expanded the |= and &= in your code, but you can write:

nbyte = (nbyte & ~(1<<4)) | (bit4Set<<4);

Note that bit4Set must be zero or one —not any nonzero value— for this to work.

Pascal Cuoq
unset, then set depending on bit4set. Haven't thought of that. Tks.
djeidot
Alexandre C.
+5  A: 

Put it in a function, the bool type will enforce 0,1 for all bitval inputs.

int change_bit(int val, int num, bool bitval)
{
    return (val & ~(1<<num)) | (bitval << num);
}
Luther Blissett
if i put it into a function I'd rather use the code I wrote. It is right, nevertheless.
djeidot
If you let the compiler inline this function in C++, then it will be as fast as if you had used the expression itself, plus you get the readability-bonus.
Luther Blissett
A: 
nbyte |= (1 << 4);

If the right hand side of the assignment, (1 << 4), is always a constant like this, then this would probably be optimized by compiler so it will be simpler in resulting assembly:

mov r0, _nbyte
mov r1, 10H         ; here is the optimization, no bit shift occured
or r0, r1
st _nbyte, r0
Donotalo
This is the answer to the question "How do I set bit 4 in nbyte?". The question is "How do I set or unset bit 4 in nbyte depending on the value of bit4Set?"
Pascal Cuoq
Thanks. I misunderstood the question. Should I delete my answer?
Donotalo
+4  A: 

This is a perfectly sensible and completely standard idiom.

Alexandre C.
+1 I see this idiom time and again in microcontroller code.
Peter G.
+1  A: 

Have you considered assigning mnemonics and/or identifiers to your bits, rather than referring to them by number?

As an example, let's say setting bit 4 initiates a nuclear reactor SCRAM. Instead of referring to it as "bit 4" we'll call it INITIATE_SCRAM. Here's how the code for this might look:

int const INITIATE_SCRAM = 0x10; // 1 << 4

...

if (initiateScram) {
    nbyte |= INITIATE_SCRAM;
} else {
    nbyte &= ~INITIATE_SCRAM;
}

This won't necessarily be any more efficient (after optimization) than your original code, but it's a little clearer, I think, and probably more maintainable.

Dan Moulding
that's pretty much the same thing. I'm actually using identifiers, I just didn't put them in the example.
djeidot
+1  A: 

This is tagged as C++ so have you considered using std::bitset instead of doing all the bit manipulation yourself? Then you can just use array notation as: bits[3] = bit4Set to set the appropriate bit.

Mark B