C++ 如何从一个长整型中提取四个无符号短整型?

C++ 如何从一个长整型中提取四个无符号短整型?,c++,c,64-bit,bit-manipulation,C++,C,64 Bit,Bit Manipulation,假设我有一个long-long整数,并希望从中提取其位并构造四个无符号短整数 具体的顺序在这里并不重要 我通常知道我需要移位并截断为无符号短int的大小。但我想我可能会在某个地方犯一些奇怪的错误,所以我问。\include #include <stdint.h> #include <stdio.h> union ui64 { uint64_t one; uint16_t four[4]; }; int main() { union ui64 n

假设我有一个long-long整数,并希望从中提取其位并构造四个无符号短整数

具体的顺序在这里并不重要

我通常知道我需要移位并截断为无符号短int的大小。但我想我可能会在某个地方犯一些奇怪的错误,所以我问。

\include
#include <stdint.h>
#include <stdio.h>

union ui64 {
    uint64_t one;
    uint16_t four[4];
};

int
main()
{
    union ui64 number = {0x123456789abcdef0};
    printf("%x %x %x %x\n", number.four[0], number.four[1],
                            number.four[2], number.four[3]);
    return 0;
}
#包括 联合ui64{ uint64_t 1; uint16_t四[4]; }; int main() { 联合ui64编号={0x123456789abcdef0}; printf(“%x%x%x%x\n”,数字.four[0],数字.four[1], 四号[2],四号[3]; 返回0; }
这应该做你想做的,而不必乱弄位转移

(unsigned short)((((unsigned long long int)value)>>(x))&(0xFFFF))

其中,
value
是您的
long-long int
x
是0、16、32或48,表示四个短整数。

您能保证结构在短整数之间没有填充吗?Ooops-我最初写了三个无符号整数。那可能会误导你。对不起。不管怎样,你的答案还是很有帮助的。它最初是
无符号短int
(每个大概2个字节——没关系)。我的观点是,除非您确定填充/对齐规则,否则该结构是危险的。位移位的问题在于,在C/C++中,负数的行为是未定义的。负数的“值”不是未定义的,而是由实现定义的。对于负“x”,它是未定义的,但在这里从未发生过。负整数的存储格式也是实现定义的(在一定的可能性范围内),因此这并不比使用并集更糟糕。我不在乎移位符号是否扩展了值,我屏蔽了除底部16位以外的所有位。这些都是很好的定义。我认为Alexander指出,负符号量右移的结果不必是0-fill或符号fill。它可以是任何东西,只要编译器文档是什么。至少在C++中。我也没有检查C标准。但在“几乎所有”编译器上,你是对的。你明白了:标准中正确的措辞是“实现定义”。我认为解决这个问题的最简单方法是首先将值转换为无符号类型。然后,该解决方案优于结构,因为它在大端和小端体系结构上产生相同的结果。这会受到小端/大端体系结构的影响吗?是的,对于大端体系和小端体系,您会得到不同的结果。这绝对是一个快速而粗糙的解决方案,顺序与:“@numbers=unpack'S4',pack'Q',$number;”在某些情况下,例如Cray和TI DSP(仅举几个CPU的例子)会出现严重故障,其中短的是/可以是32位。我100%同意这种解决方案根本不可移植。也许我应该修改答案,使用inttypes.h.:-)
(unsigned short)((((unsigned long long int)value)>>(x))&(0xFFFF))