简体   繁体   English

反转C中整数的位

[英]Reversing the bits of an integer in C

I am trying to reverse the bits of an integer in the C program. 我试图反转C程序中的整数位。 Even though I have looked at the same question by another user , I was unable to understand most of the code that was written. 即使我看了另一个用户的同一个问题 ,我也无法理解大部分编写的代码。 I have noticed that the code I have is similar to the answer by Eregrith but I cannot identify the problem with my code below: 我注意到我的代码与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);
}

If I enter reverse_bits(1) , the code returns -2147483648, which clearly did not reverse the bits of the integer 1. I am new to code and I am having difficulty locating the source of this error. 如果我输入reverse_bits(1) ,代码返回-2147483648,这显然没有反转整数1的位。我是代码新手,我很难找到此错误的来源。 Without having to change the entire code, how can I modify my existing code to return the correct output? 无需更改整个代码,如何修改现有代码以返回正确的输出?

How do you observed that it returns a negative value? 您如何观察它返回负值? unsigned int s only are used in your code... I supposed that you tried to print the returned value as an int with %d , but that is undefined behavior. unsigned int只在你的代码中使用...我猜你试图将返回的值打印为带有%dint ,但这是未定义的行为。 To print an unsigned you must use %u or %x . 要打印未签名的,您必须使用%u%x

But your reversal is wrong. 但你的逆转是错误的。 You shift the result after adding the last bit, which should be the converse. 在添加最后一位之后移动结果,这应该是相反的。 You also miss the count of bits in an unsigned int (less by one). 您还会错过unsigned int中的位数(少一个)。 The following should work: 以下应该有效:

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

---- EDIT ---- ----编辑----

As comments mentioned the possible? 正如评论中提到的可能吗? UB in the case of num begin null, I suggest to add a test to eliminate that problem: num begin null的情况下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;

Although you didn't provide the part of code that does the printing, it is somehow obvious that you are mixing int and unsigned int . 虽然您没有提供执行打印的代码部分,但显然您混合了intunsigned int

For printf() function family the specifier for unsigned int is %u so if you want to print your output, you should use: 对于printf()函数系列, unsigned int的说明符是%u因此如果要打印输出,则应使用:

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

Other than that your code is OK and besides, note that if a machine uses 2's complement and 32 bits for an int, -2147483648 = 10000000000000000000000000000000 which is a bit reversal of 1 = 00000000000000000000000000000001 . 除了你的代码是正常的,此外,请注意,如果一台机器使用2的补码和32位的int, -2147483648 = 10000000000000000000000000000000这是1 = 00000000000000000000000000000001的位反转。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM