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

How to find the nth bit of an integer in C

我有一个作业需要将一个 8 位符号大小数转换为二进制补码,然后将这两个数相加。我对如何做到这一点有一个相对好的想法,但是我不知道如何找到一个整数的第八位,这样我就可以知道这个数字有什么符号。

总体思路是符号位应该为 0 只是 return 数字,因为它已经是二进制补码,如果它是一个,那么我想在反转所有位之前将其设置为 0 ~ 运算符,然后添加 1.

提前致谢

假设您的 computer/compiler 使用二进制补码(几乎肯定是这种情况)并假设您希望结果为二进制补码。

使用 uint8_t 来保存符号和震级数。

要检查某个位是否已设置,请使用按位与运算符 &,以及对应于 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。

对于上面的任务,根本不需要用到~

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

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

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);
}

然后你可以正常添加这个号码到任何其他号码。