int main()
{
unsigned char ptr[9];
uint16_t dat = 128, s;
int i, j = 1, k;
ptr[0] = ptr[0] & 0;
j = -1;
for(i = 0;i <= 15;i++)
{
if(i % 8 == 0)
j++;
s = dat << i;
if (s & (1 << 15))
ptr[j] |= 1 << (7 - i%8);
else
ptr[j] |= 0 << (7 - i%8);
}
j = -1;
s &= 0;
for(i = 0;i <= 15;i++)
{
if(i % 8 == 0)
j++;
s |= (ptr[j] & (1 << (7 - i%8))) << (15 - i); // <-----------
s |= (ptr[j] & (1 << i%8)) << (15 - i); // Correction
}
printf("%d", s);
return(0);
}
I am trying to pack a 16 byte integer into a character array by first converting into binary and then copying it into the array bit by bit. However, I am having trouble with the marked line. I am getting 16834 as the output. What am I doing wrong here?
As written, the output is indeterminate because you never set
ptr[1]
to a known value. On my Mac, this minor variation of your code (primarily added some, headers, spaces andprintf()
statements):shows the output:
When modified to replace
ptr[0] = ptr[0] & 0;
withptr[0] = ptr[1] = 0;
, the output is:You're unlucky that your machine zeroes the stack; it is going to much harder for you to spot mistakes like uninitialized variables.
Your choice of 128 as a test value makes life difficult; there is only one bit set. Were I testing, I'd use a distinctive pattern such as 0x3CA5 (0b0011'1100'1010'0101 in C++14 binary notation). When I change the code to use 0x3CA5, I get the output:
The good news: the first loop copies the bits so that the high-order byte of the number is in
ptr[0]
and the low-order byte is inptr[1]
. The bad news: the second loop seems to mangle things horribly.Here's an instrumented version of the second loop:
The output is:
Except that the values in
s0
ands
are not what you want, and ignoring|val
, the values are what we'd expect; the basic iteration structure is under control. However, the|val
column shows that there is a problem — it was unexpected to need to use 5 hex digits in the output format! Thei - 15
shift is not placing bits where you want and need them placed.From here, you need to resolve the problem for yourself. What I hope this does is provide you with some insight in how to go about debugging such problems.
Incidentally, the question has been updated to offer:
In my test harness with 0x3CA5 as the initial value in
dat
, that produces the output:This is not the complete answer.
You don't need to do bitwise operations to achieve the result you are after; bytewise operations work fine.
It is important that you use
unsigned char
(which you are doing); if you use plainchar
(or, worse,signed char
), then you have to worry about sign bits and sign extension.As an exercise for you in bit manipulation, this has some purpose; it is worth you spending some time to fix your code so it works. As a way of manipulating the data for transmission over the network, it is not a good way of working and should be jettisoned once you've learned what you can about bit manipulation.