gstackoverflow
gstackoverflow

Reputation: 37106

ByteArrayInputStream#read() strange behaviour for negative input bytes

I faced with this code in test.

byte[] bytes = new byte[] { -1, 1, 0x0 }; 
InputStream in = new ByteArrayInputStream(bytes); 
System.out.println(in.read() + in.read() + in.read());

I expected that this code returns 0 (-1+1+0) but it returns 256.

I am very wondered.

Who can explain this bahaviour?

P.S.

Revealed that the first statement returns 255. Why?

Upvotes: 3

Views: 560

Answers (2)

Maroun
Maroun

Reputation: 95998

See the InputStream#read:

The value byte is returned as an int in the range 0 to 255

Try to print the following and you'll understand:

System.out.println(in.read());  //prints 255
System.out.println(in.read());  //prints 1
System.out.println(in.read());  //prints 0

So 256 is actually 255 + 1 + 0.

EDIT:

read() method reads one byte at a time. In Java, a byte is represented in 8-bit in two's complement, if your int is in range [128, 255] the cast to byte will be [-1, -128] respectively.

Upvotes: 2

peter.petrov
peter.petrov

Reputation: 39477

Try this code and you will see why.

import java.io.ByteArrayInputStream;
import java.io.InputStream;


public class Test006 {

    public static void main(String[] args) throws Exception {
        byte[] bytes = new byte[] { -1, 1, 0x0 }; 
        InputStream in = new ByteArrayInputStream(bytes);
        System.out.println(in.read());
        System.out.println(in.read());
        System.out.println(in.read());
    }

}

The first number is read as the int 255 and so the sum is 256.

The value -1 looks like this as a byte.
1111 1111

Apparently, when it's read as an int, Java does not add leading 1s
(to preserve the sign which would turn it into the int -1) but adds
leading zeroes. So this int becomes:

0000 0000 0000 0000 0000 0000 1111 1111

And this is the int 255 not -1.

The int -1 looks like this:

1111 1111 1111 1111 1111 1111 1111 1111

So... This is where the int 255 comes from.

Upvotes: 2

Related Questions