How to alter specific bits of a short type field?

I am very new to C++ but have to update a small utility in C++ to send some communications traffic as part of another progam. So what I have is a 16 bit short type status field named "OperStatus" with every bit or a combination of bits in it as a separate flag for some type of communication status indicator so that a lot of information is packed into this one short field. The mapping of this field is:

Bits 0-3: value to represent a number 1-15
Bits 4-15: Other individual 1-bit status flags

I have another short field named "ProgStatus" that can be a value of 1-15. So what I have to do is figure out how to get the value of ProgStatus into the first 4 bits of the OperStatus field without messing up the values of any other bits in the OperStatus field. I know how to represent whatever value in binary format (i.e. 13 = 1101) in those bits but not how to get it in there without disturbing everything else.

Thanks for any guidance anyone can provide.

Cheers,
Dennis


read this: http://en.wikipedia.org/wiki/Bitwise_operations_in_C

In your case most important is and & and or |.

if you have:
short value = 0xFFFF;
4 last bits is the last 0xF (depending on endianess);

to clear last 0xF use &:
value &= 0xF;
and then give it new value:
value |= 0xA;
or
value |= 0x7;
or anything 4 bits long

if you want assign 4 bits from another variable:
1
2
value &= 0xF;
value |= another_value & 0xF;
Last edited on
Thanks for the reply and the link. I did read the information in the link but and most ot it makes sense (other parts could not quite grasp however) but have to admit I'm not sure how to apply it to my situation, in regard to not disturbing the other bits. I think I could figure out how to get the source field value moved into target field position bits if I didn't have to worry about disturbing the other bits in the target field but I don't know how to approach that at this point with the examples provided.

What is confusing to me also is the order of things when we say 'first' or 'last' bits but I gather this is the where the term 'endianness' comes in. For my case, I need to put the value of one short field into the first four bits of another field starting from the left to right or as the field begins.

Learning new things is always a good thing but as I mentioned before I am primarily a C# UI programmer and don't usually have to deal with things at this level, and also unfortunately don't have the luxury of time to learn all the nuances of bit manipulation as much as I'd like to. At this moment I just have to get past this one tangent task I have in front of me to get back to the main project. So in that light I have provided some stub code below, in the hopes that some kind soul will provide the remainder of the logic to move the values into the proper positions while preserving the values of the existing bits.

unsigned short OperStatus; // 16 bits
// Bits: 0-3 = OSProgStatus (values 1-15)
// 4 = OSFlag1
// 5 = OSFlag2
// 6 = OSFlag3
// 7-15 = other flags...not used

short ProgStatus = 13;
// binary 1101;

// TODO: Need to stuff value of ProgStatus field into first 4 bits
// (0-3 from left to right) of OperStatus field above so they look like 1101
// also but without disturbing anything in bits 4-15 of OperStatus field.
// At this point bit 4-6 of OperStatus have values of '1' (true) each.

Thanks again for any further assistance provided.

Cheers,
Dennis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
int main()
{
    unsigned short OperStatus = 0xDEAD; // 1101 1110 1010 1101

    //clear first four bits using bitwise AND (operator &)
    //I'm using &= so the result will be stored back into OperStatus
    OperStatus &= 0x0FFF; // 0x0FFF = 0000 1111 1111 1111
    //This takes advantage of the fact that any bit ANDed with 0 = 0
    //and any bit ANDed with 1 retains its current value
    //now, OperStatus = 0x0EAD ( 0000 1110 1010 1101)

    unsigned short ProgStatus = 12;  // 0000 0000 0000 1100

    //shift the bits from their natural position up to the first 4 bits
    //and store them in a new variable
    //(that means shift them to the left 12 places)
    unsigned short ProgStatusAdjusted = (ProgStatus << 12);
    //ProgStatusAdjusted looks like this:  1100 0000 0000 0000
    //You could have put the result back into ProgStatus, but I want
    //to be clear about this step

    //set the first four bits of OperStatus using bitwise OR (operator |)
    //I'm using |= so the result will be stored back into OperStatus
    OperStatus |= ProgStatusAdjusted;
    // 0000 1110 1010 1101  |  [OperStatus]
    // 1100 0000 0000 0000     [ProgStatusAdjusted]
    //----------------------
    //=1100 1110 1010 1101
    //This takes advantage of the fact that any bit ORed with 1 = 1
    //and any bit ORed with 0 retains its current value.

    //You can see now that the first 4 bits taken alone as an
    //unsigned value equals 12, the value of ProgStatus originally.

    return 0;
}
Thank you! This makes the result and how it got there clear even to this 'bit noob'. I have always been more of a 'dismantle the machine' learner for something already in place to embed it in my mind. I will apply this and carry on.

Much thanks and regards,
Dennis
Topic archived. No new replies allowed.