i'm really confused with, well it's best if I show my code first so here's what I got.
void dumpInt(int x) throws IOException {
if ( true ) {
//8388638
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
writer.writeByte(x&0xff);
writer.writeByte((x>>8)&0xff);
writer.writeByte((x >> 16) & 0xfff);
writer.writeByte((x>>24)&0xff);
outputStream.write(x & 0xff);
outputStream.write((x >> 8) & 0xff);
outputStream.write((x >> 16) & 0xff);
outputStream.write((x >> 24) & 0xff);
System.out.println((x >> 16) & 0xff);
if(x == 8388638){
String xz = "";
byte[]array = outputStream.toByteArray();
System.out.println(array[2]+" | " + (char)array[2]);
}
} else {
writer.writeInt(x);
}
}
this works fine but when I do dumpInt(8388638), I get some weird occurrences.
writer.writeByte((x >> 16) & 0xfff) writes -128 to the writer
Im clueless as why that is.
The same thing happens for outputStream.write((x >> 16) & 0xff); but when I run System.out.println((x >> 16) & 0xff); it outputs 128(positive)
Does anybody know why this is and how I can correct it? (Sorry i'm somewhat experienced in java but im not the best by any means so if this is a really simple fix my bad)
Bytes in Java are signed, and have the range -128~127. You seem to be more familiar with the other decimal representation of a byte - the unsigned byte, having a range from 0 to 255. However, that doesn't exist in Java as a separate data type.
The following shows corresponding values between the two representations:
signed -128 -127 -126 ... -1 0 1 ... 126 127 128
unsigned 128 129 130 ... 255 0 1 ... 126 127 128
Note: these are not really different representations in binary. They have the same binary representation. It depends on whether you interpret the MSB as the sign bit or not.
You can convert from the signed version to the unsigned version by Byte.toUnsignedInt, and you can convert from the unsigned version to the signed version by casting to byte.
For some reason that you'd have to ask the API designers, OutputStream.write accepts unsigned bytes (as well as signed ones). How does Java do this if byte only ranges from -128 to 127? It accepts an int rather than a byte! This is the reason why your code compiles at all.
write (which writeByte also calls) converts the int 128 to a (signed) byte -128 and writes it into the stream. When you get the written bytes later, you are getting the converted signed byte. But in fact, in terms of the bits, 128 and -128 are the same 1000 0000. It's just that Java insists on interpreting the first 1 as a sign bit.
As I said before, you can convert the -128 to 128` if you prefer the other representation:
Byte.toUnsignedInt(-128) // 128
Note that the result must be an int, because the result is outside of byte's range.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With