Monday 26 November 2012

Puzzle 6: Multicast

int i = -1;
byte b = (byte)i;
char c = (char)b;
int i2 = (int)c;

The value of the variable in binary format is:

i = 1111 1111 1111 1111 1111 1111 1111 1111
b = 1111 1111
c = 1111 1111 1111 1111
i2 = 0000 0000 0000 0000 1111 1111 1111 1111

So we can see, from char to int, the sign is not considered. Simply prefixing 0s will do it.

If you wish to keep the sign, you need to cast char to short

short s = (short)c;
int i3 = (int)s;

result is:

s = 1111 1111 1111 1111
i3 = 1111 1111 1111 1111 1111 1111 1111 1111

If you cast byte to char, and you don't want to keep the sign. e.g. you want to achieve the following effect.

b = 1111 1111
c = 0000 0000 1111 1111

You can use bit mask:

char c = (char)(b & 0xff);

b & 0xff is of type int, so effectively

b & 0xff = 0000 0000 0000 0000 0000 0000 1111 1111

Puzzle 5: What does it mean by Hex and Octal literals are negative if their high-order bit is set?

In the book, "Java Puzzle", Puzzle 5: The Joy of Hex, there is a bold line Hex and Octal literals are negative if their high-order bit is set to explain the number 0xcafebabe is equivalent to the decimal value -889275714.

So what does "high-order bit is set" mean?

"high-order bit" is the left most bit of a given type. For example, if type is integer, which has 32 bits, then the high-order bit is the 32nd bit counting from right to left.

The 32nd bit counting from right to left is 0 in the following case, so the number is a positive number

int max = Integer.valueOf("01111111111111111111111111111111", 2);
System.out.println(max);

The result is

2147483647

which happens to be the maximum integer number.

Now let's convert the Hex format number 0xcafebabe to binary format

String s = Integer.toBinaryString(0xcafebabe);

The result is

11001010111111101011101010111110

The high-order bit is 1, therefore, it is a negative number.