4

I expected this:

ByteBuffer.wrap(new byte[] { 0, 0, 0, -34 }).getInt() == 222

However the following is true:

ByteBuffer.wrap(new byte[] { 0, 0, 0, -34 }).getInt() == -570425344

How do I get around this yet another of Java's many limitations with signed/unsigned types or do I need to completely roll my own?

Jonas
  • 121,568
  • 97
  • 310
  • 388
Jake Petroules
  • 23,472
  • 35
  • 144
  • 225

2 Answers2

6

Code:

public static void main(String[] args) {
    ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0, 0, 0, -34 });
    System.out.println(bb.order());
    System.out.println(bb.getInt() == 222);
    bb.rewind();
    bb.order(ByteOrder.LITTLE_ENDIAN);
    System.out.println(bb.order());
    System.out.println(bb.getInt() == -570425344);
}

Console:

BIG_ENDIAN
true
LITTLE_ENDIAN
true

Addendum: For reference, "The order of a newly-created byte buffer is always BIG_ENDIAN."—ByteBuffer#order()

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Edited to reflect @Mac's helpful comment. – trashgod Jun 16 '11 at 02:59
  • Sorry, you are right, I was not understanding that ByteBuffer always stores bytes in big endian order by default, not the endianness of the underlying platform. I'm running on Intel (LE) so I was reversing it. – Jake Petroules Jun 16 '11 at 03:04
  • Even ByteBuffers created by calling duplicate on a Little Endian Buffer default to Big Endian. – Michael Krussel Jun 16 '11 at 16:51
  • @Michael Krussel: Interesting; it's not mentioned explicitly in [`duplicate()`](http://download.oracle.com/javase/6/docs/api/java/nio/ByteBuffer.html#duplicate%28%29), but it makes sense as a view attribute. – trashgod Jun 16 '11 at 19:08
  • @trashgod Yeah, it would have saved me much debugging if it was explicitly mentioned in the documentation, but instead it mentions what gets duplicated, so you have to look at which attributes are missing. – Michael Krussel Jun 16 '11 at 20:51
4

The result you observe is correct for a little-endian machine. I suspect if you run the following, you'll get LITTLE_ENDIAN as the answer.

ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0, 0, 0, -34 });
System.out.println(bb.order());

If you want to force big-endian ordering for your buffer, do the following:

ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0, 0, 0, -34 });
bb.order(ByteOrder.BIG_ENDIAN);
System.out.println(bb.order());
System.out.println(bb.getInt( ));

Should print out:

BIG_ENDIAN
222
Mac
  • 14,615
  • 9
  • 62
  • 80