Reversing bits of an integer in C

I am trying to change the bits of an integer in a C program. Even if I looked at the same question by another user , I was unable to understand most of the code that was written. I noticed that the code I have is similar to Eregrith's answer , but I can't figure out the problem with my code below:

#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 the reverse_bits(1)

code will return -2147483648, which does not explicitly change the bits of integer 1. I am new to the code and I am having a hard time finding the source of this error. Without changing all of the code, how can I change my existing code to return the correct output?

+3


source to share


2 answers


Although you haven't listed the part of the code that does the printing, it is somehow obvious that you are mixing int

and unsigned int

.

For a family of functions, the printf()

specifier for unsigned int

is %u

, so if you want to print your output you should use:



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

      

Besides that your code is fine and furthermore, note that if the machine uses 2's complement and 32 bits for an int -2147483648 = 10000000000000000000000000000000

, that is a bit spread 1 = 00000000000000000000000000000001

.

+1


source


How did you notice that it returns a negative value? unsigned int

are only used in your code ... I assumed you tried to print the return value as int

with %d

, but that behavior is undefined. To print unsigned you must use %u

or %x

.

But your appeal is wrong. You carry over the result after adding the last bit, which should be reversed. You are also missing the number of bits in the unsigned int (less by one). 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 mentioned in the comments, maybe? UB in case of num

begin null, I suggest adding a test to fix this problem:

  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;

      

+2


source







All Articles