在 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 位寄存器(?),但我坚持这个,因为轮班正在发生一些事情。
有什么想法吗?
不要使用 signed 类型,而是使用 unsigned 类型。少了很多麻烦。
下面的代码允许 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));
我有一个程序
#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 位寄存器(?),但我坚持这个,因为轮班正在发生一些事情。
有什么想法吗?
不要使用 signed 类型,而是使用 unsigned 类型。少了很多麻烦。
下面的代码允许
有问题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));