4

I am trying to reverse the unsigned integer by using the '«' and '»', and bitwise 'AND' and 'OR' (& and |), but can't figure out how to do this.

What I already have;

int main(int argc, char** argv) {
    unsigned int getal;
    scanf("%i", &getal);
    printf("%X\n", getal);
    return 0;
}

User input: 0xaabbccdd, output now: AABBCCDD, what it should output DDCCBBAA

I also tried;

int main(int argc, char** argv) {
    unsigned int getal;
    unsigned int x;
    scanf("%i", &getal);
    int i;
    for (i = 0; i < 32; ++i) {
        getal <<= 1;
        getal |= (x & 1);
        x >>= 1;
        printf("%X\n", getal);
    }
    return 0;
}

but the result was completely different.

MOTIVECODEX
  • 2,624
  • 14
  • 43
  • 78

2 Answers2

3

Try this:

int getal;     // original number
int reversed;  // 4 bytes reversed of getal

/* get number form console here */

uint8_t *n1, *n2;
n1 = (uint8_t *) &getal;
n2 = (uint8_t *) &reversed;

n2[0] = n1[3];
n2[1] = n1[2];
n2[2] = n1[1]; 
n2[3] = n1[0];

/* print reversed here */
frogatto
  • 28,539
  • 11
  • 83
  • 129
  • Thank you, your code worked, but I do not really think it's a correct way to reverse bytes?.. Anyway thanks – MOTIVECODEX Feb 25 '14 at 11:33
  • @F4LLCON This solution only works with 4byte integers, also you can extend it to support other integers, As I know this solution is correct and there is no problem with it – frogatto Feb 25 '14 at 11:37
  • 1
    this may violate aliasing rules, and may not work correctly. Using simple bit shifts is the best – phuclv Mar 19 '14 at 07:19
2

Your code seems like it's trying to reverse the bits, but your indicated desired outcome is a reversal of the 8-bit groups that make up each pair of hexadecimal digits. These are not the same.

You need something like:

unsigned int reverse_nibbles(unsigned int x)
{
  unsigned int out = 0, i;
  for(i = 0; i < 4; ++i)
  {
    const unsigned int byte = (x >> 8 * i) & 0xff;
    out |= byte << (24 - 8 * i);
  }
  return out;
}

The above (untested) code assumes unsigned int is 32 bits; generalizing it is trivial but I left it out for simplicity's sake.

It simply extracts one byte (8-bit chunk) at a time from one direction, and uses bitwise or to merge it into the result from the other direction.

unwind
  • 391,730
  • 64
  • 469
  • 606