Reputation: 25558
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
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
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
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