Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting int to byte gives different results in Netbeans and JCreator

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;
    }
}
like image 279
0FiRE0 Avatar asked Dec 26 '14 15:12

0FiRE0


People also ask

What happens if we convert int to byte?

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.

Can you cast an int value into a byte variable?

An int value can be converted into bytes by using the method int. to_bytes().

What is byte casting?

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.

How are bytes stored in Java?

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.


1 Answers

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)

like image 175
fge Avatar answered Oct 12 '22 02:10

fge