Nomad
Nomad

Reputation: 978

Java >>> operator giving this output ? is it true?

I know what diffirences between >> and >>>. but I did not get the output that i expected.

example.

byte foo;

// this part printing -61 so no problem with this part
foo = -121; // -121 = 10000111
// foo >> 1 = 11000011 = -61
System.out.println( (byte) (foo >> 1) );  


foo = -121; // -121 = 10000111
// foo >>> 1 = 01000011 = 67
System.out.println( (byte) (foo >>> 1) );
// problem: why is this part printing -61 instead of 67 ?

thanks.

Upvotes: 2

Views: 85

Answers (2)

Hulk
Hulk

Reputation: 6583

Some background information in addition Louis Wasserman's excellent answer:

This is specified in jls-15.19 Shift Operators:

Unary numeric promotion (§5.6.1) is performed on each operand separately. (Binary numeric promotion (§5.6.2) is not performed on the operands.)

And the jls-5.6.1 Unary Numeric Promotion:

  • If the operand is of compile-time type Byte, Short, Character, or Integer, it is subjected to unboxing conversion (§5.1.8). The result is then promoted to a value of type int by a widening primitive conversion (§5.1.2) or an identity conversion (§5.1.1).

  • Otherwise, if the operand is of compile-time type Long, Float, or Double, it is subjected to unboxing conversion (§5.1.8).

  • Otherwise, if the operand is of compile-time type byte, short, or char, it is promoted to a value of type int by a widening primitive conversion (§5.1.2).

  • Otherwise, a unary numeric operand remains as is and is not converted.

(emphasis mine)

And 5.1.2. Widening Primitive Conversion:

A widening conversion of a signed integer value to an integral type T simply sign-extends the two's-complement representation of the integer value to fill the wider format.

Upvotes: 1

Louis Wasserman
Louis Wasserman

Reputation: 198481

>>> operates on int values, so it widens its arguments to int first. So it gets sign-extended to

 11111111111111111111111110000111

which logical right shifts to

 01111111111111111111111111000011

which, when you take the last 8 bits as a cast to byte does, gives

 11000011

which is -61.

If you don't want that implicit sign extension before the shift, you'll have to write

(byte) ((foo & 0xFF) >>> 1)

Upvotes: 7

Related Questions