1

In below code, where and what exactly I am doing wrong? I am getting unexpected values when rotating data back to left. What is the fix for this?

public class RotateExample {
    public static byte rotateRight(byte bits, int shift) {
        return (byte)((bits >>> shift) | (bits << (8 - shift)));
    }

    public static byte rotateLeft(byte bits, int shift) {
        return (byte)((bits << shift) | (bits >>> (8 - shift)));
    } 

    public static void main(String[] args)  {
        //test 1 failed
        byte a = (byte)1;
        byte b = rotateRight(a,1);
        byte c = rotateLeft(b,1);
        System.out.println(a+" "+b+" "+c);

        //test 2 passed
        a = (byte)1;
        b = rotateRight(a,2);
        c = rotateLeft(b,2);
        System.out.println(a+" "+b+" "+c);

        //test 3 failed
        a = (byte)2;
        b = rotateRight(a,2);
        c = rotateLeft(b,2);
        System.out.println(a+" "+b+" "+c);

        //test 4 passed
        a = (byte)2;
        b = rotateRight(a,3);
        c = rotateLeft(b,3);
        System.out.println(a+" "+b+" "+c);
    }
}
DT7
  • 1,615
  • 14
  • 26
Sudhakar Chavali
  • 809
  • 2
  • 14
  • 32

2 Answers2

6

The following works.

public static byte rotateRight(byte bits, int shift)
{
     return (byte)(((bits & 0xff)  >>> shift) | ((bits & 0xff) << (8 - shift)));
}
public static byte rotateLeft(byte bits, int shift)
{
    return (byte)(((bits & 0xff) << shift) | ((bits & 0xff) >>> (8 - shift)));
}

Refer to this question. Behaviour of unsigned right shift applied to byte variable

This happens because the bytes are converted to signed int before the shift operations takes place.

Community
  • 1
  • 1
Nufail
  • 1,588
  • 1
  • 17
  • 31
  • I got it... Thanks for other discussion thread that you have shared with me. – Sudhakar Chavali Oct 04 '13 at 13:35
  • Thank you! I don't know why, but it seems to work :) I just had to add the following as the first line in each method: `shift = shift % 8`. I think the method assumes that the `int` will be in a sensible range (0 to 8) – dutoitns Feb 27 '15 at 08:13
1

The current answer didn't work for me, and I realized it's because the righthand side of the operator should be shifting by the size of an Integer (32) rather than 8. This is because the byte is promoted to an Integer prior to any shifting operations taking place on it. Here is my solution:

  /**
 * Performs a circular bitwise rotation on a byte, rotating right by shift positions.
 *
 * @param bits the byte to rotate
 * @param shift the number of positions to rotate by
 * @return the rotated byte
 */
private static byte rotateRight(byte bits, int shift) {
    return (byte) (((bits & 0xff) >>> shift) | ((bits & 0xff) << (Integer.SIZE - shift)));
}

/**
 * Performs a circular bitwise rotation on a byte, rotating left by shift positions.
 *
 * @param bits the byte to rotate
 * @param shift the number of positions to rotate by
 * @return the rotated byte
 */
private static byte rotateLeft(byte bits, int shift)
{
    return (byte)(((bits & 0xff) << shift) | ((bits & 0xff) >>> (Integer.SIZE - shift)));
}

It's an old thread, but hopefully someone can find this answer useful!

grant-n
  • 74
  • 6