Can anyone explain verbosely what this accomplishes? Im trying to learn c and am having a hard time wrapping my head around it.
void tonet_short(uint8_t *p, unsigned short s) {
p[0] = (s >> 8) & 0xff;
p[1] = s & 0xff;
}
void tonet_long(uint8_t *p, unsigned long l)
{
p[0] = (l >> 24) & 0xff;
p[1] = (l >> 16) & 0xff;
p[2] = (l >> 8) & 0xff;
p[3] = l & 0xff;
}
Verbosely, here it goes:
As a direct answer; both of them stores the bytes of a variable inside an array of bytes, from left to right. tonet_short
does that for unsigned short
variables, which consist of 2 bytes; and tonet_long
does it for unsigned long
variables, which consist of 4 bytes.
I will explain it for tonet_long
, and tonet_short
will just be the variation of it that you'll hopefully be able to derive yourself:
unsigned
variables, when their bits are bitwise-shifted, get their bits shifted towards the determined side for determined amount of bits, and the vacated bits are made to be 0
, zeros. I.e.:
unsigned char asd = 10; //which is 0000 1010 in basis 2
asd <<= 2; //shifts the bits of asd 2 times towards left
asd; //it is now 0010 1000 which is 40 in basis 10
Keep in mind that this is for unsigned
variables, and these may be incorrect for signed
variables.
The bitwise-and &
operator compares the bits of two operands on both sides, returns a 1
(true) if both are 1
(true), and 0
(false) if any or both of them are 0
(false); and it does this for each bit. Example:
unsigned char asd = 10; //0000 1010
unsigned char qwe = 6; //0000 0110
asd & qwe; //0000 0010 <-- this is what it evaluates to, which is 2
Now that we know the bitwise-shift and bitwise-and, let's get to the first line of the function tonet_long
:
p[0] = (l >> 24) & 0xff;
Here, since l
is unsigned long
, the (l >> 24)
will be evaluated into the first 4 * 8 - 24 = 8
bits of the variable l
, which is the first byte of the l
. I can visualize the process like this:
abcd efgh ijkl mnop qrst uvwx yz.. .... //letters and dots stand for
//unknown zeros and ones
//shift this 24 times towards right
0000 0000 0000 0000 0000 0000 abcd efgh
Note that we do not change the l
, this is just the evaluation of l >> 24
, which is temporary.
Then the 0xff
which is just 0000 0000 0000 0000 0000 0000 1111 1111
in hexadecimal (base 16), gets bitwise-anded with the bitwise-shifted l
. It goes like this:
0000 0000 0000 0000 0000 0000 abcd efgh
&
0000 0000 0000 0000 0000 0000 1111 1111
=
0000 0000 0000 0000 0000 0000 abcd efgh
Since a & 1
will be simply dependent strictly on a
, so it will be a
; and same for the rest... It looks like a redundant operation for this, and it really is. It will, however, be important for the rest. This is because, for example, when you evaluate l >> 16
, it looks like this:
0000 0000 0000 0000 abcd efgh ijkl mnop
Since we want only the ijkl mnop
part, we have to discard the abcd efgh
, and that will be done with the aid of 0000 0000
that 0xff
has on its corresponding bits.
I hope this helps, the rest happens like it does this far, so... yeah.