反转C中整数的位

时间:2017-08-01 04:03:18

标签: c bit-manipulation

我试图反转C程序中整数的位。即使我查看the same question by another user,我也无法理解编写的大部分代码。我注意到我的代码与之类似 the answer by Eregrith但我无法通过以下代码确定问题:

#include <stdio.h>
#include <stdlib.h>

unsigned int reverse_bits(unsigned int num)
{
unsigned int reverse_num = 0; /* initialize the result*/
unsigned int count = sizeof(unsigned int) * 8 - 1; /* counter to track the number of bits in the integer*/

while (num != 0)
{
    unsigned int last_bit = num & 1; /* get the right-most bit*/
    reverse_num = reverse_num | last_bit; /* add that bit to the right-most bit of the desired reversed bits*/
    reverse_num = reverse_num << 1; /* shift the reversed bits left*/
    num = num >> 1; /* shift the original bits right*/
    count--;
}
reverse_num = reverse_num << count; /* If the original bits have only 0
s then shift the remaining bits left*/

return reverse_num;
}

int main()
{

reverse_bits(1);
}

如果我输入reverse_bits(1),代码返回-2147483648,这显然没有反转整数1的位。我是代码的新手,我很难找到此错误的来源。无需更改整个代码,如何修改现有代码以返回正确的输出?

2 个答案:

答案 0 :(得分:2)

您如何观察它返回负值? unsigned int仅在您的代码中使用...我认为您尝试将返回的值打印为int %d,但这是未定义的行为。要打印未签名的广告,您必须使用%u%x

但你的逆转是错误的。在添加最后一位之后移动结果,这应该是相反的。您还会错过unsigned int中的位数(少一个)。以下应该有效:

#include <stdio.h>
#include <stdlib.h>

unsigned int reverse_bits(unsigned int num) {
  unsigned int reverse_num = 0; /* initialize the result*/
  unsigned int count = sizeof(unsigned int) * 8; /* counter to track the number of bits in the integer*/

  while (num != 0) {
      unsigned int last_bit = num & 1; /* get the right-most bit*/
      reverse_num <<= 1; /* add one place for the next bit */
      reverse_num |= last_bit; /* add that bit to the right-most bit of the desired reversed bits*/
      num >>= 1; /* remove one bit from the original */
      count--;
    }
  reverse_num <<= count; /* If the original bits have only 0 s then shift the remaining bits left*/
  return reverse_num;
}

int main() {
  printf("%08x\n",reverse_bits(1));
  printf("%08x\n",reverse_bits(3));
  printf("%08x\n",reverse_bits(0x0F0FFFFF));
}

----编辑----

正如评论所提到的可能吗?在num的情况下,UB开始为空,我建议添加一个测试来消除该问题:

  if (count!=sizeof(reverse_num)) {
      reverse_num <<= count; /* If the original bits have only 0 s then shift the remaining bits left*/
  } else {
      reverse_num = 0;
  }
  return reverse_num;

答案 1 :(得分:1)

虽然您没有提供执行打印的代码部分,但显然您混合intunsigned int

对于printf()函数系列,unsigned int的说明符为%u,因此如果要打印输出,则应使用:

printf("%u\n", reverse_bits(1));

除了你的代码是正常的,此外,请注意,如果一台机器使用2的补码和32位的int,-2147483648 = 10000000000000000000000000000000这是1 = 00000000000000000000000000000001的一点反转。< / p>