1

I don't understand the output from the following code:

public static void main(String[] args) {
    int i1, i2, i3, i4;
    byte b;
    i1 = 128;
    b = (byte) i1;
    i2 = (int) b;
    i3 = 0 | b;
    i4 = 1 << 7;
    System.out.format("i1: %d   b: %d   i2: %d   i3: %d   i4: %d\n", i1, b, i2, i3, i4);
}

Output:

i1: 128   b: -128   i2: -128   i3: -128   i4: 128

Because byte is an 8-bit two's-complement signed integer, the binary representations with a 1 in the most significant bit are interpreted as negative values, which is why b becomes -128, which I'm totally fine with. I also understand that it's probably a good idea to keep the interpretation consistent when casting, as with i2. But shouldn't i3 and i4 have identical bit patterns and therefore map to identical int values?

3
  • i would just like to express my indignation about Java's bytes. As I learned it, byte is by definition a number between 0 and 255 and therefore the complete mess they have done to byte in Java can not be excused. The -128..127 calls for a new primitive data type. Commented Apr 21, 2009 at 8:56
  • 1
    I would like to see that definition. The definitions I googled say that a byte is 8 bits, enough to represent a character. Commented Apr 21, 2009 at 20:54
  • I guess I just got so used to the idea that the color components R G B are BYTES in range 0..255. Also the ASCII table maps characters to numbers in this range. I have never tried typing Alt+(-)+(number), it's always been a positive number 0..255. I was appalled by the conception of byte data type in Java. Commented Apr 26, 2009 at 15:43

7 Answers 7

5

In this line:

i3 = 0 | b;

The "b" variable is automatically promoted to int type with sign extension because of the | operator, so becomes (int)-128, i.e. 0xffffff80.

When "or"ed with zero, its still the same value, namely -128

Sign up to request clarification or add additional context in comments.

Comments

4

Sign extension is what is making i2 and i3 negative.

In the expression (0 | b), b is promoted to an int, and sign extension occurs as part of this promotion.

That's not happening in the expression assigned to i4. The constants 1 and 7 are already ints so there's no sign extension involved.

2 Comments

I would have said that 1 and 7 are int type and so is the result so that why is no sign extension involved.
Yeah - that's both more correct and easier to understand than what I wrote - edited the answer to reflect this.
4

No, i4 is not a byte value, it's an int. That means that its sign bit is bit 31, not bit 7.

UPDATE: i3 is an int too, but it is initialized by extending a byte, so it keeps the sign from the byte value.

2 Comments

But i3 is also an int... why is it negative then?
The i3 assignment is similar to the i2 assignment... The expression returns a byte that is cast to an int.
2

i2 = (int) b;

i3 = 0 | b;

the i3 statement is equivalent to:

i3 = 0 | ((int) b) = 0 | i2 so naturally it is going to have the same value as i2

Comments

1

That's simple. i3 = 0 | b; gets evaluated like byte, then it is converted to int. Whereas i4 = 1 << 7; will evaluate value as int and assign it to int. So in the first case we get 10000000b cast to int from byte, which will give us -128. And in the second we just assign this value to int without cast, which gives us 128.

Comments

1

If you want to get the unsigned value of the bit pattern in a byte:

b & 0xff

See also this old answer.

1 Comment

Do you happen to know the exact reason why & works and | doesn't?
1

In

i3 = 0 | b;

I'm guessing the 0 | b part is evaluated as a byte, and the results are then cast to an int, while in

i4 = 1 << 7;

the 1 << 7 part is already an int.

The above guess has been pointed out in the comments to be wrong!

The correct version is: In the top expression, the b is already cast to an int with sign extension before the OR operation.

1 Comment

“0 | b” is not evaluated as a byte. “b” is widened to int before the OR operation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.