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);
}
精彩评论