3

I convert a short number to a 3 byte array using the following code:

static byte[] convertTo3ByteArray(short s) {

   byte[] ret = new byte[3];
   ret[0] = (byte) (s & 0xff);
   ret[1] = (byte) ((s >> 8) & 0xff);
   ret[2] = (byte) (0x00);

   return ret;
}

This works very well.

I found a code on Stackoverflow to convert the array back to a number:

static int convertToInt(byte[] b) {
   return ((b[0] << 0) | (b[1] << 8) | (b[2] << 16));
}

And when I convert 258 to byte array, and then use this code, it returns 258.

But for number 675, this code returns -93.

How do I have to change the convertToShort method to get 675 back? I suppose it has something to do with bitshift and loss of data? Or signed bytes?

Alexander Ciesielski
  • 10,506
  • 5
  • 45
  • 66

3 Answers3

4

Try with this modified method:

static int convertToShort(byte[] b) {
    return (((b[0] & 0xFF) << 0) | ((b[1] & 0xFF) << 8) | ((b[2] & 0xFF) << 16));
}

In the array some bytes are negative, you need to convert them back to "positive values" with byteVal & 0xFF before doing the bit shift

morgano
  • 17,210
  • 10
  • 45
  • 56
  • Is there are difference between using "byteVal" and "byteVal & 0xFF"? Why , how ? Arent they same thing ? – Davut Özcan Jul 31 '14 at 13:06
  • @DavutÖzcan lets suppose that we have `short shortVal = 255; byte byteVal = shortVal;`, then the value of `byteVal` would be -1. If I do `byteVal & 0xFF` then the JVM do this: internally "converts" byteVal to int (of value -1) then it does the `&` bit op with 0xFF returning an integer value (255). In summary: not the same thing (byteVal = -1 and byteVal & 0xFF = 255) – morgano Jul 31 '14 at 13:19
1

A short has 16 bits of information, so that would be two bytes. When you try to store a third byte with | (b[2] << 16), it would go off the end of the short's bits, which is a problem. I.e. you can't do what you want to.

The Guy with The Hat
  • 10,836
  • 8
  • 57
  • 75
1

Changing to using a char datatype will fix this issue as they are the only unsigned type in Java:

https://stackoverflow.com/a/21089624/1590490

static char[] convertTo3ByteArray(short s) {

    char[] ret = new char[3];
    ret[0] = (char) (s & 0xff);
    ret[1] = (char) ((s >> 8) & 0xff);
    ret[2] = (char) (0x00);

    return ret;
}

static int convertToShort(char[] b) {
    return ((b[0]) | (b[1] << 8) | (b[2] << 16)); // the original << 0 shift does nothing
}
Community
  • 1
  • 1
Lyndon Armitage
  • 417
  • 4
  • 11