将整数转换为 BYTE 值
Convert an integer to BYTE value
我正在尝试向串行通信端口写入一些命令。假设我需要将 10 个字节的数据发送到 comm 端口。现在,在这 10 个字节中,数据消息类似于:
Byte offset 0 - message id
Byte offset 1-4 - unix time in format 1432419028
Byte offset 5-10 - data
我的问题是如何转换 unix 时间 1432419028 以适合我的 BYTE 数组。
平台是 C++ Visual Studio。
我有一些样本可以写成这样
BYTE initmsg[10];
unsigned int* UNALIGNED epoch_time = (unsigned int*) &initmsg[1];
*epoch_time = 12345678;
但我想构建如下所示的 initmsg。
initmsg[1] = 0x01;
initmsg[2] = 0x01;
initmsg[3] = 0x01;
initmsg[4] = 0x01;
正确的可移植方式是,在 Big-Endian 中:
uint32_t time = ...;
initmsg[1] = (time >> 24) & 0xFF;
initmsg[2] = (time >> 16) & 0xFF;
initmsg[3] = (time >> 8) & 0xFF;
initmsg[4] = time & 0xFF;
在 Little-Endian 中:
uint32_t time = ...;
initmsg[1] = time & 0xFF;
initmsg[2] = (time >> 8) & 0xFF;
initmsg[3] = (time >> 16) & 0xFF;
initmsg[4] = (time >> 24) & 0xFF;
使用什么字节顺序与使用的体系结构无关,但应在文档中指定。如果不是,那么,试错...
更新:这是为什么?您必须查看这些位,例如中间字节之一:
31 24 16 8 0
time:
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
time >> 16:
> > > > > > > > > > > > > > > > X X X X X X X X X X X X X X X X
(time >> 16) & 0xFF:
0xFF = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
& > > > > > > > > > > > > > > > > X X X X X X X X X X X X X X X X
= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 X X X X X X X X
也就是说,您移动位以将您想要的位放在位位置 0-7 中,然后使用 0xFF 执行二进制与操作,将除 0-7 之外的任何其他位清零。自然地,您在分配给数组时被截断为一个字节,因此这最后一步并不是绝对必要的,但我发现一个很好的做法是明确地执行 & 0xFF
.
用十六进制思考也很有用:
1432419028 = 0x5560FAD4
0x5560FAD4 >> 24 = 0x55
0x5560FAD4 >> 16 = 0x5560
0x5560FAD4 >> 8 = 0x5560FA
0x5560FAD4 >> 0 = 0x5560FAD4
(0x5560FAD4 >> 24) & 0xFF = 0x55
(0x5560FAD4 >> 16) & 0xFF = 0x60
(0x5560FAD4 >> 8) & 0xFF = 0xFA
(0x5560FAD4 >> 0) & 0xFF = 0xD4
我正在尝试向串行通信端口写入一些命令。假设我需要将 10 个字节的数据发送到 comm 端口。现在,在这 10 个字节中,数据消息类似于:
Byte offset 0 - message id
Byte offset 1-4 - unix time in format 1432419028
Byte offset 5-10 - data
我的问题是如何转换 unix 时间 1432419028 以适合我的 BYTE 数组。 平台是 C++ Visual Studio。
我有一些样本可以写成这样
BYTE initmsg[10];
unsigned int* UNALIGNED epoch_time = (unsigned int*) &initmsg[1];
*epoch_time = 12345678;
但我想构建如下所示的 initmsg。
initmsg[1] = 0x01;
initmsg[2] = 0x01;
initmsg[3] = 0x01;
initmsg[4] = 0x01;
正确的可移植方式是,在 Big-Endian 中:
uint32_t time = ...;
initmsg[1] = (time >> 24) & 0xFF;
initmsg[2] = (time >> 16) & 0xFF;
initmsg[3] = (time >> 8) & 0xFF;
initmsg[4] = time & 0xFF;
在 Little-Endian 中:
uint32_t time = ...;
initmsg[1] = time & 0xFF;
initmsg[2] = (time >> 8) & 0xFF;
initmsg[3] = (time >> 16) & 0xFF;
initmsg[4] = (time >> 24) & 0xFF;
使用什么字节顺序与使用的体系结构无关,但应在文档中指定。如果不是,那么,试错...
更新:这是为什么?您必须查看这些位,例如中间字节之一:
31 24 16 8 0
time:
X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X
time >> 16:
> > > > > > > > > > > > > > > > X X X X X X X X X X X X X X X X
(time >> 16) & 0xFF:
0xFF = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
& > > > > > > > > > > > > > > > > X X X X X X X X X X X X X X X X
= 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 X X X X X X X X
也就是说,您移动位以将您想要的位放在位位置 0-7 中,然后使用 0xFF 执行二进制与操作,将除 0-7 之外的任何其他位清零。自然地,您在分配给数组时被截断为一个字节,因此这最后一步并不是绝对必要的,但我发现一个很好的做法是明确地执行 & 0xFF
.
用十六进制思考也很有用:
1432419028 = 0x5560FAD4
0x5560FAD4 >> 24 = 0x55
0x5560FAD4 >> 16 = 0x5560
0x5560FAD4 >> 8 = 0x5560FA
0x5560FAD4 >> 0 = 0x5560FAD4
(0x5560FAD4 >> 24) & 0xFF = 0x55
(0x5560FAD4 >> 16) & 0xFF = 0x60
(0x5560FAD4 >> 8) & 0xFF = 0xFA
(0x5560FAD4 >> 0) & 0xFF = 0xD4