在 C 中以 64 位整数存储值

Store values in 64 bit integer in C

我有一个程序

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

int main(void)
{

int i;
int x = 128;
int y = 128;
int z = 2;
int32_t coordinates = x | (y << 12) | (z << 16);

fprintf(stdout, "x = %d\n", (coordinates & 0xFF));
fprintf(stdout, "y = %d\n", ((coordinates >> 8) & 0xFF));
fprintf(stdout, "z = %d\n", ((coordinates >> 16) & 0xFF));
}

x,y,z 存储在 32 位寄存器中,但仅对 { (x,y,z)< 256} 成功。如果我希望 x,y,z 能够获得 2^10 (1024) 的值(所以 (x,y,z)<1024),这怎么可能发生?我知道我应该使用 64 位寄存器(?),但我坚持这个,因为轮班正在发生一些事情。

有什么想法吗?

  1. 不要使用 signed 类型,而是使用 unsigned 类型。少了很多麻烦。

  2. 下面的代码允许 x 在与 y 冲突之前有一个 12 位的范围。它允许 y 在与 z 碰撞之前有一个 4 位(16 - 12)的范围。 16 位 int/unsigned.

    有问题
    int32_t coordinates = x | (y << 12) | (z << 16);
    

要允许 x,y,z 具有 10 位范围,请将 y 移动 10,将 z 移动 10+10。

 uint32_t coordinates = x | ((uint32_t)y << 10) | ((uint32_t)z << 20);

精确数值:
(一定要使用匹配的打印说明符。)

#include <inttypes.h>
...
fprintf(stdout, "x = %" PRIu32 "\n", (coordinates & 0x3FF));
fprintf(stdout, "y = %" PRIu32 "\n", ((coordinates >> 10) & 0x3FF));
fprintf(stdout, "z = %" PRIu32 "\n", ((coordinates >> 20) & 0x3FF));

如果你有 3 个 10 位的字段,它们将适合 32 位的 int。您可以按如下方式进行:

int32_t coordinates = (int32_t)(x & 0x3ff) | 
                      ((int32_t)(y & 0x3ff) << 10) | 
                      ((int32_t(z & 0x3ff) << 20);

您首先对每个数字执行 0x3ff 的按位与操作,以确保您只获得最低的 10 位。然后将结果强制转换为结果的类型,以确保当值被移动时,它不会为中间值移动太多。然后每个值通过移位放置在 10 位偏移处。

然后您可以按如下方式读回它们:

fprintf(stdout, "x = %d\n", (coordinates & 0x3FF));
fprintf(stdout, "y = %d\n", ((coordinates >> 10) & 0x3FF));
fprintf(stdout, "z = %d\n", ((coordinates >> 20) & 0x3FF));