Originally Posted by
doia
Thanks guys! It is starting to make sense now.
However I just can't understand this part of the code
Code:
n = (666<<12) + 666;
Could you please elaborate as to why you added 666 after the left shift?
That could be any number less than or equal to 2048, which is the highest value you can fit in an unsigned 12-bit number. When you shift bits, anything "shifted in", is zero, eg, a one byte value equal to 1:
00000001
Now shift this <<4:
00010000
Now shift that >>2:
00000100
So here's the same code (using two different numbers instead), and reversing the process afterward (which you would have to when reading this file). Also, I changed everything to unsigned. IF YOU NEED TO USE NEGATIVE NUMBERS SAY SO, THAT WILL BE A SIGNIFICANT COMPLICATION:
Code:
#include <stdio.h>
#include <string.h>
typedef struct {
unsigned int v :24; /* 24-bits = 3 bytes */
#pragma pack(1) /* make sure struct is 3 bytes */
} twelveX2;
int main() {
twelveX2 eg;
unsigned int n, copy = 0, a, b;
n = (666<<12) + 444;
memcpy(&eg,&n,3);
/* extraction */
memcpy(©,&eg,3);
a = b = copy;
a &= ~(~0<<12); // zero out upper bits
b = b>>12; // zero out lower bits
printf("eg size: %ld bytes. lower value: %u upper value: %u\n",sizeof(eg), a, b);
return 0;
}
The output is:
eg size: 3 bytes. lower value: 444 upper value: 666
Here's how "a &= ~(~0<<12)" works:
~ is the "complement operator", it reverses all the bits (try google).
So ~0 is all bits set. Shift that 12 to the left, and you have an int with the lower 12 bits unset, the upper set:
11111111 11111111 11110000 00000000
Now, ~ (ie, flip) that and:
00000000 00000000 00001111 11111111
This is the "AND" mask that we want. AND'ing a number with that will zero out anything past the lower twelve bits. That's the how we get the lower value.
The upper value is simple, you just shift >>12.