The code below, produces the following output on a serial console
[42][25][f][27][0][0]
。
我的问题是 - 如果只是串口输出 - 你怎么知道这个数字是9999?数学如何运作?我认为这与小端有关吗?
int a = 9999;
buf[0] = 'B';
buf[1] = '%';
buf[2] = a&0xff;
buf[3] = (a>>8)&0xff;
buf[4] = (a>>16)&0xff;
buf[5] = (a>>24)&0xff;
答案 0 :(得分:2)
Endianness确定数字在内存中的存储方式,而不是如何对其执行算术运算。由于您提供的C代码仅使用整数运算(即不处理指针和内存访问),因此无论字节顺序如何,结果数据都是相同的。
要序列化您的号码,您可以通过应用位移(分别为0,8,16和24位)来提取数字的每个字节(&0xff
);例如0xAABBCCDD >> 8
变为0xAABBCC
,二进制AND操作&0xff
会丢弃高位字节以保留最低有效字节,例如0xCC
。
要撤消该操作,必须将字节和AND组合在一起,在相反方向上应用位移。解析i
将使用以下代码:
int a = buf[2] & (buf[3] << 8) & (buf[4] << 16) & (buf[5] << 24);
这里不需要转换任何操作数,因为在C中使用按位运算符意味着整数提升(ISO / IEC9899§6.3.1.1),并且您得到的变量类型是int
- 也就是说,假设buf
是一个unsigned
8位整数类型的数组。
请注意,这假设序列化数据的发射器也具有32位int
长度,并使用相同的带符号数表示(通常为two's complement)。
答案 1 :(得分:0)
了解数据如何嵌入到消息中,您可以推断它们以正确的格式转换。
#include <stdio.h>
#include <stdint.h>
int main(void)
{
int32_t a = 9999;
unsigned char buf[6];
buf[0] = 'B';
buf[1] = '%';
buf[2] = a&0xff;
buf[3] = (a>>8)&0xff;
buf[4] = (a>>16)&0xff;
buf[5] = (a>>24)&0xff;
uint32_t res= buf[2] + ((buf[3] & 0xFFFFFFFFu) << 8) + ((buf[4] & 0xFFFFFFFFu) << 16) + ((buf[5] & 0xFFFFFFFFu) << 24);
printf("Converted from chars: %d\n", res);
return 0;
}
当数据被推入缓冲区时,您可以将它们放回到int变量中的正确位置。
Endianness并不重要,因为考虑到其架构,在主机平台上进行轮班操作。我认为它与小端有关?
答案 2 :(得分:0)
河西十进制数系统是基数为16的数字系统。 这意味着它由16个不同的符号组成,其权重为16.
这意味着不是只有10个符号(0-9)来说明数字,如十进制(基数10)系统,你有16 0-f。 在十进制中符号a = 10,b = 11,c = 12,d = 13,e = 14和f = 15。
系统的权重部分意味着十六进制数字中的第一个符号的权重为1,十进制系统也是如此。 但如果数字由多个数字表示,则该权重增加16。
所以在十六进制中:
ff =(16 ^ 1 * 15)+15十进制。
fff =(16 ^ 2 * 15)+(16 ^ 1 * 15)+15十进制
这个数字系统广泛用于电子工程和软件开发附近的硬件,因为它允许用四组分组,从而说明更大的二进制数。