如何在两个32位整数中存储64位整数并再次转换回来

Sto*_*lly 27 c++

我很确定它只是一些按位操作的问题,我只是不完全确定我应该做什么,并且所有搜索都返回"64位对32位".

Jac*_*ack 37

包:

u32 x, y;
u64 v = ((u64)x) << 32 | y;
Run Code Online (Sandbox Code Playgroud)

解压:

x = (u32)((v & 0xFFFFFFFF00000000LL) >> 32);
y = (u32)(v & 0xFFFFFFFFLL);
Run Code Online (Sandbox Code Playgroud)

  • 解包时不需要显式位掩码; `x =(u32)(v >> 32); y =(u32)v;`完成工作. (27认同)

lhf*_*lhf 10

或者,如果您对两个32位数字的含义不感兴趣:

u32 x[2];
u64 z;
memcpy(x,&z,sizeof(z));
memcpy(&z,x,sizeof(z));
Run Code Online (Sandbox Code Playgroud)

  • Goz,这不是关于性能,而是关于代码美的我(我的!)感知. (2认同)

Vik*_*ehr 8

使用联合并摆脱位操作:

<stdint.h> // for int32_t, int64_t

union {
  int64_t big;
  struct {
    int32_t x;
    int32_t y;
  };
};
assert(&y == &x + sizeof(x));
Run Code Online (Sandbox Code Playgroud)

就那么简单.big由x和y组成.

  • +1 表示联合,但最好使用 `&lt;stdint.h&gt;` 中的标准固定大小类型,即 `int32_t`、`int64_t`,因为不保证 sizeof(long) 和 sizeof(long long)是任何特定的值。 (2认同)
  • 我的错误导致了未定义的行为。根据规范,如果您写入 big,则不能假设 x 和 y 包含任何内容。联盟中唯一包含有效数据的成员是大的。大多数编译器确实支持它,但它是未定义的行为。使用固定大小的 memcpy 确实会更好,任何有价值的优化器都会优化掉。 (2认同)
  • 这应该被投票作为答案。移位操作假定 64 位数字的特定存储顺序(大端/小端),因此本质上不可移植。我假设编译器将按照底层硬件/操作系统支持的顺序处理联合。 (2认同)