-2

I'm having a little trouble writing my code to rotate my hexadecimal digits right. Below is a function I wrote, where, if you call on it, passing it like so: rotr(0x12345678, 4), it should return 0x81234567. Instead, it's only returning 7 digits (as opposed to eight, like in the original value = 0x12345678).

Can someone please help me understand what is going on in the bit level? I'm having trouble understanding why my current code is returning 0x123456f, instead of 0x81234567. Thanks in advance!

Edit: is it because I'm shifting 0x12345678 too early? I'm mainly trying to figure out why only seven digits return back, as opposed to eight.

unsigned int rotr(unsigned int x, int n) {
    int i; //iterate for loop
    unsigned int y; //masked last bit
    unsigned int z; //final result

    for (i=1; i<=n; i++) {
        y = x & 0x1; //isolates last bit
        x = x >> 1; //shift right 1
        z = x | (y << (sizeof(x)-1)); //shifts mask back to first slot; OR
                                      //it with x
    }

    return z;
}
B.M. Corwen
  • 205
  • 3
  • 10

2 Answers2

3

sizeof(x) will give the size of the variable in bytes, while the shift operators work with numbers of bits. You need to convert these operands to use the same unit.

Thiago Barcala
  • 6,463
  • 2
  • 20
  • 23
  • It worked using 32-1, instead of using sizeof(x)-1. However, does using 32 work in all cases? I am only trying to rotate bits, so had n equalled 3, the result should be 2468ACF, or 0000 0010 0100 0110 1000 1010 1100 1111. – B.M. Corwen Nov 14 '17 at 01:27
  • int doesn't have a guaranteed size, but you can find the bits with a little math. https://stackoverflow.com/questions/3200954/what-is-char-bit – Retired Ninja Nov 14 '17 at 02:00
0

instead of sizeof(x) you should write 8*sizeof(x), it's looks generic because your input may be short int, long int or anything.

For Right Rotation instead of rotating loops you can try below logic.

#include<stdio.h>
unsigned int rotr(unsigned int x, int n) {
        unsigned int z;
        z = (x >> n) | (x << (8*sizeof(int) - n)) ; 
        return z;
}
int main()
{
        unsigned  int num= 0x12345678, n = 4, ret;

        printf("before : %x\n",num);
        ret= rotr(num,n);
        printf("before : %x\n",ret);
}
Achal
  • 11,821
  • 2
  • 15
  • 37
  • What's the difference between the two codes? I tried using the code above (replacing sizeof(x) with sizeof(int)*8-1) with your function here, and while the code above and your code both work for rotating 0x12345678, mine doesn't work if I were to put, say 0x1234 (I have to account my code for any hexadecimal and decimal value). Yours seems to work for 0x1234 as well, while mine doesn't. – B.M. Corwen Nov 14 '17 at 16:10
  • z = x | (y << (8*sizeof(x)-1)), its not working because whether "y" is 0 or 1 always you are moving y to 31st position only but it shouldn't always. – Achal Nov 14 '17 at 16:38
  • @B.M.Corwen have you got ? take simple example & note down binary for each iteration. you will get surely – Achal Nov 14 '17 at 16:52
  • Why shouldn't it always move y to the 31st position? I apologize if the answer to the question seems obvious, but I'm a beginner and I can't seem to grasp this concept very well. Edit: I am finding that if you shift a bit right off, I can't seem to add y = 0 into the beginning of x. It seems that leading zeros disappear. – B.M. Corwen Nov 14 '17 at 17:13