문제

The goal is to convert every pair of bytes as a single unsigned 16bit int. In C I would define an array[500] of 16bit unsinged int pointer and would point it the the array of bytes, but in java I am not aware of such short cut. I know in Java there is no 16bit data type except char, however that is not an issue. We only need to copy every two consecutive two bytes into a single int of an array of integers. So the array of integer holds values of int ranging from 0 to 65535 (2^16-1).

도움이 되었습니까?

해결책

I think that there are no nice tricks in Java like the aliasing you can do in C. You're going to have to do this by hand:

public int[] pack(byte[] bytes) {
    int n = bytes.length >> 1;
    int[] packed = new int[n];
    for (int i = 0; i < n; ++i) {
        int i2 = i << 1;
        int b1 = bytes[i2] & 0xff;
        int b2 = bytes[i2 + 1] & 0xff;
        packed[i] = (b1 << 8) | b2;
    }
    return packed;
}

(This can probably be sped up a bit, but probably not worth it for 1,000 elements unless it's being done a lot.) Note that the promotion from byte to int requires a bit of extra work to deal with unwanted sign extension.

다른 팁

You could use ByteBuffer to spare the shifting and masking, which you often get wrong. (and there is signed vs. unsigned too)

ByteBuffer bb = ByteBuffer.wrap(bytes);
bb.order(ByteOrder.BIG_ENDIAN);  // or LITTLE_ENDIAN
short[] shorts = new short[bytes.length/2];
for (int i=0; i<shorts.length; i++)
   shorts[i] = bb.getShort();

Note - if you really want an "unsigned short", there is no such thing in java, so your array would have to be of integers. You would convert using

for (int i=0; i<intArray.length; i++) {
   short s = bb.getShort();
   intArray[i] = s & 0xFFFF; // mask off all the high order bits
}

There isn't really an unsigned 16-bit integer type in Java -- except maybe char, if you're feeling abusive of the language. That said, this is a wonderful time to use the popular Guava utility library:

public short[] pack(byte[] bytes) {
   short[] result = new short[bytes.length / 2];
   for (int i = 0; i < bytes.length; i += 2) {
     result[i/2] = Shorts.fromBytes(bytes[i], bytes[i+1]);
   }
}

And if you're really picky about performance, you could add a separate counter or use right shift instead of division, but that's straightforward enough.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top