按位 C - 从无符号整数中解包带符号的 10 位数字
Bitwise C - Unpacking signed 10 bit numbers from an unsigned int
我被要求创建一个函数,它将接受一个无符号的 32 位整数,并从无符号整数中解压缩 3 个有符号的 10 位整数。这个任务的上下文是一个解包函数,它以一个 32 位无符号整数作为输入,一个长度为 3 的数组称为 xyz,并用从原始 int 解包的 x、y 和 z 坐标占据数组,这些坐标是 10 位有符号整数。
我写了下面的程序,它似乎对正值工作正常,但对负值却不行。我尝试打印输出坐标的十六进制值以更好地了解底层二进制文件,对我来说一切似乎都很好,但解释的数字是错误的。对于有符号整数,编译器使用二进制补码来解释二进制。
void coordinates(unsigned int p, int xyz[3]) {
unsigned int z = ((p << 22) >> 22) & 0x800003FF;
xyz[0] = (~0 << 32) | (p >> 20) ;
xyz[1] = (~0 << 32) | (p >> 10) & 0x3FF;
xyz[2] = (~0 << 32) | z;
}
如果您还有其他问题,请告诉我,我会尽力解答。
以下应该适合您:
void coordinates(unsigned int p, int xyz[3])
{
xyz[0] = (p >> 20) & 0x3FF; // Get 10 Bits
if(xyz[0] & 0x200) // Check MSB
xyz[0] |= 0xFFFFFC00; // Sign Extend
xyz[1] = (p >> 10) & 0x3FF;
if(xyz[1] & 0x200)
xyz[1] |= 0xFFFFFC00;
xyz[2] = p & 0x3FF;
if(xyz[2] & 0x200)
xyz[2] |= 0xFFFFFC00;
}
int main(void)
{
int s10[3];
unsigned int u32 = 0xFFFFFFFF;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
u32 = 0x1FF7FDFF;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
u32 = 0x20080200;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
u32 = 0x00000000;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
return 0;
}
输出
$ gcc main.c -o main.exe; ./main.exe;
FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
-1 -1 -1 -1
1FF7FDFF 000001FF 000001FF 000001FF
536346111 511 511 511
20080200 FFFFFE00 FFFFFE00 FFFFFE00
537395712 -512 -512 -512
00000000 00000000 00000000 00000000
0 0 0 0
我被要求创建一个函数,它将接受一个无符号的 32 位整数,并从无符号整数中解压缩 3 个有符号的 10 位整数。这个任务的上下文是一个解包函数,它以一个 32 位无符号整数作为输入,一个长度为 3 的数组称为 xyz,并用从原始 int 解包的 x、y 和 z 坐标占据数组,这些坐标是 10 位有符号整数。
我写了下面的程序,它似乎对正值工作正常,但对负值却不行。我尝试打印输出坐标的十六进制值以更好地了解底层二进制文件,对我来说一切似乎都很好,但解释的数字是错误的。对于有符号整数,编译器使用二进制补码来解释二进制。
void coordinates(unsigned int p, int xyz[3]) {
unsigned int z = ((p << 22) >> 22) & 0x800003FF;
xyz[0] = (~0 << 32) | (p >> 20) ;
xyz[1] = (~0 << 32) | (p >> 10) & 0x3FF;
xyz[2] = (~0 << 32) | z;
}
如果您还有其他问题,请告诉我,我会尽力解答。
以下应该适合您:
void coordinates(unsigned int p, int xyz[3])
{
xyz[0] = (p >> 20) & 0x3FF; // Get 10 Bits
if(xyz[0] & 0x200) // Check MSB
xyz[0] |= 0xFFFFFC00; // Sign Extend
xyz[1] = (p >> 10) & 0x3FF;
if(xyz[1] & 0x200)
xyz[1] |= 0xFFFFFC00;
xyz[2] = p & 0x3FF;
if(xyz[2] & 0x200)
xyz[2] |= 0xFFFFFC00;
}
int main(void)
{
int s10[3];
unsigned int u32 = 0xFFFFFFFF;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
u32 = 0x1FF7FDFF;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
u32 = 0x20080200;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
u32 = 0x00000000;
coordinates(u32, s10);
printf("%08X %08X %08X %08X\n", u32, s10[0], s10[1], s10[2]);
printf("%d %d %d %d\n", u32, s10[0], s10[1], s10[2]);
return 0;
}
输出
$ gcc main.c -o main.exe; ./main.exe; FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF -1 -1 -1 -1 1FF7FDFF 000001FF 000001FF 000001FF 536346111 511 511 511 20080200 FFFFFE00 FFFFFE00 FFFFFE00 537395712 -512 -512 -512 00000000 00000000 00000000 00000000 0 0 0 0