According to a comment from OP: cannot be reproduced any more
I use NetBeans to develop my Java programs, and they work perfectly. But when I make a JAR file of my program, it gives me different output for the same input.
I had a hard time debugging, and I found that in NetBeans when I cast int
to byte
the result ranges in [-128; 128)
, while the same code in JCreator is in [0; 256)
How can I make the range always [-128; 128)
?
private static byte[] convertHexString(String ss) {
try{
byte digest[] = new byte[ss.length() / 2];
for (int i = 0; i < digest.length; i++) {
String byteString = ss.substring(2 * i, 2 * i + 2);
int byteValue = Integer.parseInt(byteString, 16);
digest[i] = (byte) byteValue;
}
// Test
for(int i = 0; i < digest.length; ++i){
System.out.println(digest[i]);
}
return digest;
}
catch(Exception e){
return null;
}
}
When an integer value is converted into a byte, Java cuts-off the left-most 24 bits. We will be using bitwise AND to mask all of the extraneous sign bits.
An int value can be converted into bytes by using the method int. to_bytes().
In Java, there are two types of casting: Widening Casting (automatically) - converting a smaller type to a larger type size. byte -> short -> char -> int -> long -> float -> double. Narrowing Casting (manually) - converting a larger type to a smaller size type. double -> float -> long -> int -> char -> short -> byte.
The byte data type in Java is a signed integer based on the two's complement 8-bit mechanism. It is different from the int data type that uses 4 bytes (i.e., 32-bit to store a number). The values that can be stored in a single byte are -128 to 127. byte data types are primitive.
It definitely looks like a bug. A byte
ranges from -128 to 127, not 0 to 255.
Here is what I think is happening with a byte value of -1 (ie 0Xff), where it prints 255 instead:
public static void main(final String... args)
{
final ByteBuffer buf = ByteBuffer.allocate(4);
// What Java would do on casting...
buf.put((byte) 0xff);
buf.put((byte) 0xff);
buf.put((byte) 0xff);
buf.put((byte) 0xff);
buf.rewind();
System.out.println(buf.getInt()); // -1 -- good
buf.rewind();
// What JCreator seems to do on casting...
buf.put((byte) 0);
buf.put((byte) 0);
buf.put((byte) 0);
buf.put((byte) 0xff);
buf.rewind();
System.out.println(buf.getInt()); // 255 -- WRONG
}
That is, when "upcasting" from byte to int, whatever Java compiler you use doesn't do what the JLS requires it to do, that is, to carry the sign bit.
I seriously doubt that the compiler/runner you use is Oracle's JDK at the command line too for that reason.
(note that a PrintStream
has a method to print an int
, but not a byte
; therefore the byte is promoted to an int)
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