如何在C中找到整数的第n位

时间:2016-03-07 13:17:18

标签: c binary twos-complement

我已经完成了一项任务,我需要将8位符号幅度数转换为2的补码,然后添加这两个数字。我对如何做到这一点有了一个相对好的想法,但是我不知道如何找到一个整数的第八位,这样我就可以知道该数字的符号。

总的想法是,如果符号位为0,则只返回数字,因为它已经是2的补码,如果它是1,那么我想将它设置为0,然后用〜反转所有位运算符然后添加1.

提前致谢

2 个答案:

答案 0 :(得分:1)

假设您的计算机/编译器使用了两个补码(几乎可以肯定),并假设您希望结果为二进制补码。

使用uint8_t来保存符号和幅度编号。

要检查是否设置了位,请使用按位AND运算符&以及与msb对应的位掩码。要获得与位 n 对应的位掩码,请将值移位1 n 。在C代码中:

#define SIGN (1 << 7)

uint8_t sm = ...;
if(sm & SIGN)     // if non-zero, then the SIGN bit is set
{
}
else              // it was zero, the SIGN bit is not set
{
}

要进行实际转换,有几种方法。我只是掩盖并复制数字的相关部分,再次按位AND:

#define MAGNITUDE 0x7F

int8_t magnitude = sm & MAGNITUDE; // variable magnitude is two's compl.

编辑完整解决方案(因为有人已经发布了一个):

#define SIGN (1 << 7)
#define MAGNITUDE 0x7F

uint8_t sm = ...;
int8_t  twos_compl = sm & MAGNITUDE;

if(sm & SIGN)     // if non-zero, then the SIGN bit is set
{
  twos_compl = -twos_compl;
}

int8_t x = ...; // some other number in two's complement
int16_t result = twos_compl + x;

作为旁注,在将~运算符与小整数类型混合时要非常小心,因为它执行隐式整数提升。例如uint8_t x = 1然后~my_uint8给你0xFFFFFFFE(32位系统)而不是你想象的0xFE。

对于上述任务,根本不需要使用~

答案 1 :(得分:1)

您可以通过创建仅具有该位设置的掩码并使用逻辑AND来检查是否设置了高位,以查看结果是否为非零。

一旦知道设置了高位,就可以通过翻转所有位并添加一位来转换为二进制补码。

uint8_t x = (some value)
if (x & (1 << 7)) {
    printf("sign bit set\n");
    x = (uint8_t)((~(x & (0x7F))) & 0xFF) + 1;
    printf("converted value: %02X\n", x);
}

然后您可以正常将此号码添加到其他任何人。