Tony Stark
Tony Stark

Reputation: 25558

After reading in bytes from file, most are right except 1 is wrong and negative

In Java, I just read a file into a ByteBuffer. When I started checking to make sure that the ByteBuffer contained the right bytes, I noticed that it had mostly the correct start and end bytes, except for the 3rd byte, it has -117 instead of what emacs says should be 139 (8b in hexl-mode). What gives? Does this have something to do with Big/Little Endian..?

Just to be clear, according to emacs the first four bytes should be:

1f:8b:08:00 which is equal to 31 139 8 0

and my java gets:

31 -117 8 0

Any ideas?

Upvotes: 1

Views: 472

Answers (3)

erickson
erickson

Reputation: 269817

This is a bit of a tangent, but if you are trying to work with signed bytes, the following might prove useful.

Since most operations will promote a Java byte to int—preserving the sign and magnitude—it is very common to mask off the high-order bits, like this:

/* Convert two bytes from an array to a 16-bit, unsigned value. */
int val = (b[idx] & 0xFF) << 8 | (b[idx + 1] & 0xFF);

Before applying the & operator (and most other operators), a byte is widened to an int (or even a long, depending on the context). So a signed byte value of 0xFF is converted to a signed integer value of 0xFFFFFF.

But normally when doing bit-wise operations, the intent to to treat each byte as an unsigned value, so the byte 0xFF (-1) should just be the int 0xFF (255). The masking with 0xFF accomplishes this.

Upvotes: 2

Samir Talwar
Samir Talwar

Reputation: 14330

Java's integral types (including byte) are signed: they range from -128 to 127, rather than 0 to 255 like you might expect. Any number with a high bit of 1 (1### ####) will be negative.

Lots of people have written about this.

Upvotes: 3

Pavel Minaev
Pavel Minaev

Reputation: 101615

Java byte is signed, and therefore its range is -128..127 rather than 0..255. Taking that into account, your bytes are correct. If the unsigned value of the byte is X, signed one is (X - 256) - thus, for 139, the signed value is 139 - 256 = -117.

Upvotes: 5

Related Questions