char[] 到 uint32_t 无法正常工作
char[] to uint32_t not working properly
我正在使用以下方法将 char[4]
转换为 uint32_t
。
frameSize = (uint32_t)(frameSizeBytes[0] << 24) | (frameSizeBytes[1] << 16) | (frameSizeBytes[2] << 8) | frameSizeBytes[3];
frameSize
是一个 uint32_t
变量,frameSizeBytes
是一个 char[4]
数组。例如,当数组包含以下值(十六进制)
00 00 02 7b
frameSize
设置为 635,这是正确的值。此方法也适用于其他字节组合,但以下
除外
00 00 9e ba
对于这种情况,frameSize
设置为 4294967226,根据 this website,这是不正确的,因为它应该是 40634。为什么会发生这种行为?
您的 char
类型已在您的特定实现中签名,并通过大多数运算符进行整数提升。在使用有符号数组元素的地方使用强制转换为 unsigned char
。
编辑: 实际上正如 Olaf 在评论中指出的那样,您实际上应该更喜欢强制转换而不是 unsigned int
(假设常见的 32 位 unsigned int
)或 uint32_t
以避免 << 24
移位操作的潜在未定义行为。
为了保持整洁,我建议使用以下行的内联函数:
static inline uint32_t be_to_uint32(void const *ptr)
{
unsigned char const *p = ptr;
return p[0] * 0x1000000ul + p[1] * 0x10000 + p[2] * 0x100 + p[3];
}
注意:通过使用 unsigned long
常量,这段代码避免了 unsigned char
被提升为有符号 int
然后 multiplication/shift 导致整数溢出的问题(一个C) 恼人的历史特征。当然,您也可以按照 Olaf 的建议使用 ((uint32_t)p[0]) << 24
。
我正在使用以下方法将 char[4]
转换为 uint32_t
。
frameSize = (uint32_t)(frameSizeBytes[0] << 24) | (frameSizeBytes[1] << 16) | (frameSizeBytes[2] << 8) | frameSizeBytes[3];
frameSize
是一个 uint32_t
变量,frameSizeBytes
是一个 char[4]
数组。例如,当数组包含以下值(十六进制)
00 00 02 7b
frameSize
设置为 635,这是正确的值。此方法也适用于其他字节组合,但以下
00 00 9e ba
对于这种情况,frameSize
设置为 4294967226,根据 this website,这是不正确的,因为它应该是 40634。为什么会发生这种行为?
您的 char
类型已在您的特定实现中签名,并通过大多数运算符进行整数提升。在使用有符号数组元素的地方使用强制转换为 unsigned char
。
编辑: 实际上正如 Olaf 在评论中指出的那样,您实际上应该更喜欢强制转换而不是 unsigned int
(假设常见的 32 位 unsigned int
)或 uint32_t
以避免 << 24
移位操作的潜在未定义行为。
为了保持整洁,我建议使用以下行的内联函数:
static inline uint32_t be_to_uint32(void const *ptr)
{
unsigned char const *p = ptr;
return p[0] * 0x1000000ul + p[1] * 0x10000 + p[2] * 0x100 + p[3];
}
注意:通过使用 unsigned long
常量,这段代码避免了 unsigned char
被提升为有符号 int
然后 multiplication/shift 导致整数溢出的问题(一个C) 恼人的历史特征。当然,您也可以按照 Olaf 的建议使用 ((uint32_t)p[0]) << 24
。