开发者

Parsing 32 bit integer in C program

I have a 32 bit inte开发者_如何学Pythonger, split into parts like this:

 --------------------------------------
 | Part1         | Part2    | Part 3  |
 --------------------------------------

Part 1 higher 16 bits. (Part 2 + Part 3) = lower 16 bits.

Part 2 is 10 bits and Part 3 is 6 bits

I need help on how do we read and update part 1, part2 and part 3 in C program.


Given an integer x with the above format, you can replace Part2 like this:

x = (x & ~(0x3ff << 6)) | (newPart2 << 6);

and Part3 like so:

x = (x & ~0x3f) | newPart3;

This assumes that both newPart2 and newPart3 are e.g. unsigned int with their new values right-adjusted.


int i

To extract the individual parts

part1 = (i & 0xFFFF0000) >> 16

part2 = (i & 0x0000FFC0) >> 6

part3 = (i & 0x0000003F) 

To compose the integer

i = (part1 << 16) | (part2 << 6) | (part3)


Try cast to this structure

struct {
    uint32_t part_1:16;
    uint32_t part_2:10;
    uint32_t part_3:6;
} parts;

Could be the one below depending on endianness

  struct {
        uint32_t part_1:6;
        uint32_t part_2:10;
        uint32_t part_3:16;
    } parts;

Obviously not portable!

Since you need to read and update, a pointer will do. For example, if you 32bit value is called x, you do the following

parts *ptr = (parts *)&x;

ptr->part_2 = <part2 update>


The theory to be used behind this are and, or and shift operations with masks.

To access some bits of the integer, first create a mask where there are ones in the bits you want to be used. Now apply and and(&) operation between the mask and the integer. According to the behavior of the & the bits where the mask is 0 will be 0 and where the mask is 1 will have the value of that bit in the integer. Now that we have only the bits we want we align them to the right, that is done shifting the bits to the right the correct number of positions as to leave the rightmost bit of the mask in the less significant position of the byte.

To write in a part of a byte, we need fist to nullify what was in that part for that we use the negated mask that is used to read that part. Once that part is negated we apply an or(|) operation with the new value that must be aligned to that position.

To read:

unsigned int read_part_1(unsigned int composed) {
   return (composed & 0xffff0000) >> 16;
}

unsigned int read_part_2(unsigned int composed) {
   return (composed & 0x0000ffc0) >> 6;
}

unsigned int read_part_3(unsigned int composed) {
   return (composed & 0x0000003f);
}

To write(val aligned to the right):

unsigned int write_part_1(unsigned int composed, unsigned int val) {
   return (composed & ~0xffff0000) | ((val & 0x0000ffff) << 16);
}

unsigned int write_part_2(unsigned int composed, unsigned int val) {
   return (composed & ~0x0000ffc0) | ((val & 0x000003ff) << 10);
}

unsigned int write_part_3(unsigned int composed, unsigned int val) {
   return (composed & ~0x0000003f) | (val & 0x0000003f);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜