Say I have a byte like this 1010XXXX where the X values could be anything. I want to set the lower four bits to a specific pattern, say 1100, while leaving the upper four bits unaffected. How would I do this the fastest in C?
4 Answers
In general:
value = (value & ~mask) | (newvalue & mask); mask is a value with all bits to be changed (and only them) set to 1 - it would be 0xf in your case. newvalue is a value that contains the new state of those bits - all other bits are essentially ignored.
This will work for all types for which bitwise operators are supported.
2 Comments
You can set all those bits to 0 by bitwise-anding with the 4 bits set to 0 and all other set to 1 (This is the complement of the 4 bits set to 1). You can then bitwise-or in the bits as you would normally.
ie
val &= ~0xf; // Clear lower 4 bits. Note: ~0xf == 0xfffffff0 val |= lower4Bits & 0xf; // Worth anding with the 4 bits set to 1 to make sure no // other bits are set. 2 Comments
To further generalise the answers given, here are a couple of macros (for 32-bit values; adjust for different bitfield lengths).
#include <stdio.h> #include <stdint.h> #define MASK(L,P) (~(0xffffffff << (L)) << (P)) #define GET_VAL(BF,L,P) (((BF) & MASK(L,P)) >> P) #define SET_VAL(BF,L,P,V) ( (BF) = ((BF) & ~MASK(L,P)) | (((V) << (P)) & MASK(L,P)) ) int main(int argc, char ** argv) { uint32_t bf = 1024; printf("Bitfield before : %d , 0x%08x\n", bf, bf); printf("Mask(5,3): %d , 0x%08x\n", MASK(5,3), MASK(5,3)); SET_VAL(bf,5,3,19); printf("Bitfield after : %d , 0x%08x\n", bf, bf); return 0; } As an aside, it's ridiculous that the C bitfield is completely useless. It's the perfect syntactic sugar for this requirement but due to leaving it up to each compiler to implement as it sees fit, it's useless for any real-world usage.
Comments
Use the bitwise OR operator, |, when you want to change the bit of a byte from 0 to 1.
Use the bitwise AND operator, &, when you want to change the bit of a byte from 1 to 0.
Example
#include <stdio.h> int byte; int chb; int main() { // Change bit 2 of byte from 0 to 1 byte = 0b10101010; chb = 0b00000100; // 0 to 1 change byte printf("%d\n", byte); // Display current status of byte byte = byte | chb; // Perform 0 to 1 single bit changing operation printf("%d\n", byte); // Change bit 2 of byte back from 1 to 0 chb = 0b11111011; // 1 to 0 change byte byte = byte & chb; // Perform 1 to 0 single bit changing operation printf("%d\n", byte); } Maybe there are better ways; I don’t know. This will help you for now.
1 Comment
byte that is the same value as the value you began with. May I ask, "What is the point of that?"