【问题标题】:How to find the nth bit of an integer in C如何在C中找到整数的第n位
【发布时间】:2016-03-07 13:17:17
【问题描述】:

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

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

提前致谢

【问题讨论】:

  • 到现在为止,请拿出你的努力。
  • 嗯……如果有符号变量的最后一位是 1,那么 x < 0 应该是真的……你不必检查具体的位。
  • 您可以为此使用&0b01111111 & bits,不管怎样,结果的第八位都会设置为 0。
  • "...然后将这两个数字相加" 并表示答案如何?采用哪种格式?二进制补码?
  • 您指的是要添加哪两个数字?符号大小和二进制补码格式相同的数字?

标签: c binary twos-complement


【解决方案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);
}

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

【讨论】:

  • 或者只是int8_t result = x &amp; 0x7F; if(x &amp; (1&lt;&lt;7)) result = -result; 更具可读性并且可能稍微快一些。
【解决方案2】:

假设您的计算机/编译器使用二进制补码(几乎可以肯定是这种情况)并假设您希望结果为二进制补码。

使用uint8_t 来保存符号和大小。

要检查是否设置了位,请使用按位与运算符&amp;,以及对应于 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
{
}

要进行实际的转换,有几种方法。我只是将数字的相关部分屏蔽并复制,再次使用按位与:

#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。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 1970-01-01
    • 2023-04-04
    • 2020-02-26
    相关资源
    最近更新 更多