Search code examples
javabit-manipulationbitwise-operatorsshort

Get 8 shorts from a short


I have an array a of short like this one:

a = [ 16748, 
      26979, 
      25888, 
      30561, 
      115
    ] //in decimal

a = [ 0100000101101100, 
      0110100101100011, 
      0110010100100000, 
      0111011101100001, 
      0000000001110011
    ] //in binary

I would like to obtain another array b of shorts composed by representing each pair of bits of each short. (It's diffucult to explain but easy to understand using an example).

So, for the array a I will obtain array b:

b = [ 01, 00, 00, 01, 01, 10, 11, 00, 
      01, 10, 10, 01, 01, 10, 00, 11, 
      01, 10, 01, 01, 00, 10, 00, 00, 
      01, 11, 01, 11, 01, 10, 00, 01, 
      00, 00, 00, 00, 01, 11, 00, 11
    ]

In pseudocode I thought of doing so:

int lenght = (16/2) * a.length; //16*2 because I had short (16 bit) and I want sequences of 2 bit
short[] b = new short[length]; //I create the new array of short
int j = 0; //counter of b array
foreach n in a { //foreach short in array a
    for(int i = 16 - 2; i > 0; i-2) { //shift of 2 positions to right
        b[j] = ( (n >> i) & ((2^2)-1) ); //shift and &
        j++;
    }
}

I tried to translate this pseudocode (assumnig it's correct) to Java:

public static short[] createSequencesOf2Bit(short[] a) {
    int length = (16/2) * a.length; 
    short[] b = new short[length];

    for(int i = 0; i < a.length; i++) {
        int j = 0; 
        for(short c = 16 - 2; c > 0; c -= 2) {
            short shift = (short)(a[i] >> c);
            b[j] = (short)(shift & 0x11);
            j++;
        }
    }
    return b;
} 

But if I print b[] I don't obtain what I want. For example, considering only the first short in a (16748 = 0100000101101100). I obtain:

[1, 0, 16, 1, 1, 16, 17]

That is completely wrong. Infact I should get:

b = [ 01, 00, 00, 01, 01, 10, 11, 00,
      ...
    ] //in binary

b = [ 1, 0, 0, 1, 1, 2, 3, 0,
      ...
    ] //in decimal  

Can someone help me? Thanks a lot.


That's strange. If I consider only the first short in a and I print b I get:

public static short[] createSequencesOf2Bit(short[] a) {
    int length = (16/2) * a.length; 
    short[] b = new short[length];

    //for(int i = 0; i < a.length; i++) {
        int j = 0; 
        for(short c = (16 - 2); c >= 0; c -= 2) {
            short shift = (short)(a[0] >> c);
            b[j] = (short)(shift & 0x3);
            j++;
        }
    //}
    for(int i = 0; i < b.length; i++) {
        System.out.println("b[" + i + "]: " + b[i]);
    }
    return b;
} 

b = [1 0 0 1 1 2 3 0 0 0 0 0 ... 0]

But if I print this one:

public static short[] createSequencesOf2Bit(short[] a) {
    int length = (16/2) * a.length; 
    short[] b = new short[length];

    for(int i = 0; i < a.length; i++) {
        int j = 0; 
        for(short c = (16 - 2); c >= 0; c -= 2) {
            short shift = (short)(a[i] >> c);
            b[j] = (short)(shift & 0x3);
            j++;
        }
    }
    for(int i = 0; i < b.length; i++) {
        System.out.println("b[" + i + "]: " + b[i]);
    }
    return b;
} 

b = [0 0 0 0 1 3 0 3 0 0 0 0 ... 0]

Solution

  • I suspect the main issue is that instead of & 0x11 you want & 0x3. Remember that 0x means hexadecimal, so 0x11 gives you the number 17, not 3. Or you could write 0b11 to get 11 in binary.

    Additionally, as pointed out in the comments, the loop condition should be c >= 0, not c > 0.