将 2 字节十六进制数转换回十进制

标签 c hex endianness

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;

最佳答案

字节序决定了数字如何存储在内存中,而不是如何对其执行算术。由于您提供的 C 代码仅使用整数算术(即不处理指针和内存访问),因此无论字节序如何,结果数据都将相同。

要序列化您的号码,您可以通过应用位移位(分别为 0、8、16 和 24 位)来提取号码的每个字节 (&0xff);例如0xAABBCCDD >> 8 变为 0xAABBCC,二进制 AND 运算 &0xff 会丢弃高位字节以保留最低有效字节(在示例中)它是0xCC

要撤消该操作,您必须将字节与它们组合在一起,并沿相反方向应用位移位。解析 i 将使用以下代码:

int a = buf[2] & (buf[3] << 8) & (buf[4] << 16) & (buf[5] << 24);

此处无需转换任何操作数,因为在 C 中使用按位运算符意味着整数提升 (ISO/IEC 9899§6.3.1.1),并且生成的变量类型为 int — 即是,假设 buf 是一个无符号 8 位整数类型的数组。

请注意,这假设序列化数据的发射器也具有 32 位 int 长度,并使用相同的有符号数字表示形式(通常 two's complement )。

关于将 2 字节十六进制数转换回十进制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38896643/

相关文章:

java - 十六进制转 Ascii? java

c++ - 尝试输入十六进制值时,程序在 scanf ("%x",&foo) 上崩溃

C 40 位字节交换(endian)

c - 确定小端机器地址的十六进制值

iphone - 用memcpy反转字节序

c - 使用 ualarm 的问题

C 数组 char 与数组 int 比较

c - 有没有办法将没有显式命名类型的结构作为参数传递给函数?

c - 在 Linux shell 中通过 ODBC 驱动程序与数据库通信的实用程序

c++ - 由 4 个十六进制字符组成的数字