views:

116

answers:

4

How can I split the 64 bit input into 16 bits?

A: 

given that value contains your 64bit number

 char a1 = (char) (value & 0xffff);
 char a2 = (char) ((value>>16) & 0xffff);
 char a3 = (char) ((value>>32) & 0xffff);
 char a4 = (char) ((value>>48) & 0xffff);

edit: added casts as suggested by commenter

Toad
where is the string?
Murali VP
when a 64-bit value is copied to a 16-bit primitive and only lower 16 bits will get copied what is the point in and-ing with 0xffff?
Murali VP
It isn't clear if they mean a literal `String` or just 64 bits.
jjnguy
@Murali VP: To overcome problems with sign extension
Draemon
starblue
@starblue: If I would have used a short like you suggest, it would have been wrong. Since a short is a signed type. and char is unsigned and therefore correct. Sticks hand out to receive the stolen -1 back
Toad
No, in Java char should only be used for text characters. Short is perfectly fine for storing 16 bits, see this answer for details: http://stackoverflow.com/questions/397867/port-of-random-generator-from-c-to-java/397997#397997
starblue
starblue: I think just using the char type is much easier than you and and casting tricks. And who says char may only be used exclusively for characters? It's just an unsigned 16 bit int... nothing magical about it
Toad
+4  A: 
String s = someStringOfBits;
String s0 = someStringOfbits.substring(0, 16);
String s1 = someStringOfbits.substring(16, 32);
String s2 = someStringOfbits.substring(32, 48);
String s3 = someStringOfbits.substring(48, 64);

This is assuming you actually have a string that looks similar to this:

1010101010101010101010101010101010101010101010101010101010101010
jjnguy
+2  A: 

Using a ByteBuffer:

ByteBuffer buf = ByteBuffer.allocate(Long.SIZE / Byte.SIZE);
buf.asLongBuffer().put(0, value);
short a0 = buf.asShortBuffer().get(0);
short a1 = buf.asShortBuffer().get(1);
short a2 = buf.asShortBuffer().get(2);
short a3 = buf.asShortBuffer().get(3);
finnw
+1  A: 

Here's an inappropriately generic way of doing it :):

public class MyClass

{ 

    static public long[] splitIntoNBits(long value, int numBitsPerChunk){      

        long[] retVal = null;

        if(numBitsPerChunk == 64){
            retVal = new long[1];
            retVal[0] = value;
            return retVal;
        }

        if(numBitsPerChunk <= 0 || numBitsPerChunk > 64){
            return null;
        }

        long mask = (1 << numBitsPerChunk) - 1;      
        int numFullChunks = (byte) (64 / numBitsPerChunk);
        int numBitsInLastChunk = (byte) (64 - numFullChunks * numBitsPerChunk);
        int numTotalChunks = numFullChunks;
        if(numBitsInLastChunk > 0){
            numTotalChunks++;
        }

        retVal = new long[numTotalChunks];

        for(int i = 0; i < numTotalChunks; i++){
            retVal[i] = value & mask;
            value >>= numBitsPerChunk;
        }

        // clean up the last chunk
        if(numBitsInLastChunk > 0){
            mask = (1 << numBitsInLastChunk) - 1;
            retVal[retVal.length - 1] &= mask;
        }

        return retVal;

    }       




    public static void main(String[] args) 
    {       
        long myvalue = ((long) 0x12345678) | (((long) 0xABCDEF99) << 32);       
        long[] bitFields = splitIntoNBits(myvalue, 16);
        for(int i=0; i < bitFields.length; i++){
            System.out.printf("Field %d: %x\r\n", i, bitFields[i]);
        }
    } 
}

produces output:

Field 0: 5678
Field 1: 1234
Field 2: ef99
Field 3: abcd

and for a bitsPerField of 7 it produces:

Field 0: 78
Field 1: 2c
Field 2: 51
Field 3: 11
Field 4: 11
Field 5: 73
Field 6: 7b
Field 7: 66
Field 8: 2b
Field 9: 1

Isn't that fun!?

vicatcu