Any*_*orn 4 c c++ signed byte packing
我需要将四个带符号的字节打包成32位整数类型.这就是我的目标:
int32_t byte(int8_t c) { return (unsigned char)c; }
int pack(char c0, char c1, ...) {
return byte(c0) | byte(c1) << 8 | ...;
}
Run Code Online (Sandbox Code Playgroud)
这是一个很好的解决方案?它是便携式的(不是通信意义上的)吗?是否有现成的解决方案,或许可以提升?
问题我最关心的是将负位从char转换为int时的位顺序.我不知道应该是什么样的正确行为.
谢谢
char不保证签名或未签名(在PowerPC Linux上,char默认为unsigned).传播这个词!
你想要的是像这样的宏:
#include <stdint.h> /* Needed for uint32_t and uint8_t */
#define PACK(c0, c1, c2, c3) \
(((uint32_t)(uint8_t)(c0) << 24) | \
((uint32_t)(uint8_t)(c1) << 16) | \
((uint32_t)(uint8_t)(c2) << 8) | \
((uint32_t)(uint8_t)(c3)))
Run Code Online (Sandbox Code Playgroud)
这很难看,主要是因为它与C的操作顺序不相符.此外,反斜杠返回是有的,所以这个宏不必是一个大的长行.
另外,我们在转换为uint32_t之前转换为uint8_t的原因是为了防止不必要的符号扩展.
我喜欢Joey Adam的答案,除了它是用宏编写的(在许多情况下会导致真正的痛苦),如果'char'不是1字节宽,编译器就不会给你一个警告.这是我的解决方案(基于Joey的).
inline uint32_t PACK(uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3) {
return (c0 << 24) | (c1 << 16) | (c2 << 8) | c3;
}
inline uint32_t PACK(sint8_t c0, sint8_t c1, sint8_t c2, sint8_t c3) {
return PACK((uint8_t)c0, (uint8_t)c1, (uint8_t)c2, (uint8_t)c3);
}
Run Code Online (Sandbox Code Playgroud)
我已经省略了将c0-> c3转换为uint32_t,因为编译器在转换时应该为你处理这个问题,并且我使用c风格的转换,因为它们适用于c或c ++(OP标记为两者).