tags:

views:

224

answers:

4

I know Java doesn't allow unsigned types, so I was wondering how it casts an integer to a byte. Say I have an integer a with a value of 255 and I cast the integer to a byte. Is the value represented in the byte 11111111? In other words, is the value treated more as a signed 8 bit integer, or does it just directly copy the last 8 bits of the integer?

Thanks,

helixed

+6  A: 

This is called a narrowing primitive conversion. According to the spec:

A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.

So it's the second option you listed (directly copying the last 8 bits).

I am unsure from your question whether or not you are aware of how signed integral values are represented, so just to be safe I'll point out that the byte value 1111 1111 is equal to -1 in the two's complement system (which Java uses).

Michael Myers
Yeah, I knew about two's compliment. So, just to clarify, if I have an long type with a value of -1, and I cast it to an int, the result will be 65535? Thanks for the quick and detailed reply by the way.
helixed
@helixed: No, it will also be -1 because it is also all ones. Anything in the range of the smaller type will be converted to the equivalent value.
Michael Myers
Oh wait, I see. Because of 2's complement, any negative value inside of the range of the smaller type will be padded with 1's (in binary) anyway, so the result will always retain its sign. Thanks again.
helixed
@helixed: Yes, that's correct. Once you get outside the range of the smaller type, it's effectively the same as overflow or underflow.
Michael Myers
A: 

Just a thought on what is said: Always mask your integer when converting to bytes with 0xFF (for ints). (Assuming myInt was assigned values from 0 to 255).

e.g.

char myByte = (char)(myInt & 0xFF);

why? if myInt is bigger than 255, just typecasting to byte returns a negative value (2's complement) which you don't want.

The Elite Gentleman
char is two bytes big in java.
Paul
`char` is 16 bits in java. If you change your example to `byte` it doesn't work either and could still yield a negative value. You could mask with 0x7F, but then negative values wouldn't convert correctly. The good way to ensure you don't run into problems is probably to `assert -128 <= myInt `
Philippe Beaudoin
@Philippe, thanks. I'm working very late so I wrote this too fast but yet, how big is `short` in java?
The Elite Gentleman
`short` is a signed two-byte type, while `char` is an unsigned two-byte type.
Michael Myers
I understand what you were trying to say, and it's good advice in general. In my specific case, I already know the value in the int is less than 255.
helixed
+1  A: 

or does it just directly copy the last 8 bits of the integer

yes, this is the way this casting works

Roman
+1  A: 
int i = 255;

byte b = (byte)i;

So the value of be in hex is 0xFF but the decimal value will be -1.

int i = 0xff00;

byte b = (byte)i;

The value of b now is 0x00. This shows that java takes the last byte of the integer. ie. the last 8 bits but this is signed.

Paul