Hugh
Hugh

Reputation: 1212

Convert short to byte[] in Java

How can I convert a short (2 bytes) to a byte array in Java, e.g.

short x = 233;
byte[] ret = new byte[2];

...

it should be something like this. But not sure.

((0xFF << 8) & x) >> 0;

EDIT:

Also you can use:

java.nio.ByteOrder.nativeOrder();

To discover to get whether the native bit order is big or small. In addition the following code is taken from java.io.Bits which does:

And visa versa.

Upvotes: 58

Views: 112449

Answers (10)

Talijanac
Talijanac

Reputation: 1157

Following methods will read and write short value, in BIG_ENDIAN ordering, to/from arbitary placement in byte array. The code is more efficient than using ByteBuffer as no heap allocation occurs.

//
// Write BIG_ENDIAN short to an array at given index.
// Same, but more efficient than: 
//   ByteBuffer.wrap(arr).order(ByteOrder.BIG_ENDIAN).putShort(idx, val)
//
static void putShort(short val, byte[] arr, int idx) {
    arr[idx]     = (byte) (val >>> 8);
    arr[idx + 1] = (byte) val;
}

//
// Read BIG_ENDIAN short from an array at given index.
// Same, but more efficient than: 
//   ByteBuffer.wrap(arr).order(ByteOrder.BIG_ENDIAN).getShort(idx)
//
static short getShort(byte[] arr, int idx) {
    return (short) (               // low two bytes of int composed
         (0xff & arr[idx]) << 8    // from high byte
       | (0xff & arr[idx + 1])     // and low byte
    );
}

Upvotes: 0

Serg Burlaka
Serg Burlaka

Reputation: 2496

Short to bytes convert method In Kotlin works for me:

 fun toBytes(s: Short): ByteArray {
    return byteArrayOf((s.toInt() and 0x00FF).toByte(), ((s.toInt() and 0xFF00) shr (8)).toByte())
}

Upvotes: 9

short to byte

short x=17000;    
byte res[]=new byte[2];    
res[i]= (byte)(((short)(x>>7)) & ((short)0x7f) | 0x80 );    
res[i+1]= (byte)((x & ((short)0x7f)));

byte to short

short x=(short)(128*((byte)(res[i] &(byte)0x7f))+res[i+1]);

Upvotes: 0

bvdb
bvdb

Reputation: 24740

Several methods have been mentioned here. But which one is the best? Here follows some proof that the following 3 approaches result in the same output for all values of a short

  // loops through all the values of a Short
  short i = Short.MIN_VALUE;
  do
  {
    // method 1: A SIMPLE SHIFT
    byte a1 = (byte) (i >> 8);
    byte a2 = (byte) i;

    // method 2: AN UNSIGNED SHIFT
    byte b1 = (byte) (i >>> 8);
    byte b2 = (byte) i;

    // method 3: SHIFT AND MASK
    byte c1 = (byte) (i >> 8 & 0xFF);
    byte c2 = (byte) (i & 0xFF);

    if (a1 != b1 || a1 != c1 ||
        a2 != b2 || a2 != c2)
    {
      // this point is never reached !!
    }
  } while (i++ != Short.MAX_VALUE);

Conclusion: less is more ?

byte b1 = (byte) (s >> 8);
byte b2 = (byte) s;

(As other answers have mentioned, watch out for LE/BE).

Upvotes: 5

Hugh
Hugh

Reputation: 1212

Figured it out, its:

public static byte[] toBytes(short s) {
    return new byte[]{(byte)(s & 0x00FF),(byte)((s & 0xFF00)>>8)};
}

Upvotes: 7

David
David

Reputation: 4047

An alternative that is more efficient:

    // Little Endian
    ret[0] = (byte) x;
    ret[1] = (byte) (x >> 8);

    // Big Endian
    ret[0] = (byte) (x >> 8);
    ret[1] = (byte) x;

Upvotes: 20

Gili
Gili

Reputation: 90023

A cleaner, albeit far less efficient solution is:

ByteBuffer buffer = ByteBuffer.allocate(2);
buffer.putShort(value);
return buffer.array();

Keep this in mind when you have to do more complex byte transformations in the future. ByteBuffers are very powerful.

Upvotes: 50

Scott Izu
Scott Izu

Reputation: 2309

public short bytesToShort(byte[] bytes) {
     return ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
}

public byte[] shortToBytes(short value) {
    byte[] returnByteArray = new byte[2];
    returnByteArray[0] = (byte) (value & 0xff);
    returnByteArray[1] = (byte) ((value >>> 8) & 0xff);
    return returnByteArray;
}

Upvotes: 1

abc
abc

Reputation: 1342

It depends how you want to represent it:

  • big endian or little endian? That will determine which order you put the bytes in.

  • Do you want to use 2's complement or some other way of representing a negative number? You should use a scheme that has the same range as the short in java to have a 1-to-1 mapping.

For big endian, the transformation should be along the lines of: ret[0] = x/256; ret[1] = x%256;

Upvotes: 3

Alexander Gessler
Alexander Gessler

Reputation: 46607

ret[0] = (byte)(x & 0xff);
ret[1] = (byte)((x >> 8) & 0xff);

Upvotes: 87

Related Questions