首页 > 解决方案 > 按位 C - 从无符号整数中解压缩有符号的 10 位数字

问题描述

我被要求创建一个函数,它将采用一个无符号的 32 位整数并从无符号整数中解压缩 3 个有符号的 10 位整数。这个任务的上下文是一个解包函数,它接受一个 32 位无符号整数作为输入和一个称为 xyz 的长度为 3 的数组,并使用从原始整数解包的 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;
}

如果您有任何进一步的问题,请告诉我,我会尽力回答。

标签: cbit-manipulationbitwise-operatorsbit-shift

解决方案


以下内容应该适合您:

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

推荐阅读