I am unable to understand the following:
In java,
long l = 130L;
byte b = (byte)l;
If I print the value of b, why do I get -126? What is the bit representation of long l?
A byte is a sequence of 8 bits, which makes 2^8 cases = 256. Half of them represent negative numbers, which is -128 to -1. Then there is the 0, and about the half, 1 to 127 represent the positive numbers.
130 as Int looks like 128 + 2 which is:
0000:0000 1000:0000 (128)
0000:0000 0000:0010 (2)
0000:0000 1000:0010 (130)
However, the Byte has just 8 digits, and the assignment takes just the bits as they are, but just the last ones:
1000:0010
The first bit indicates, it is a negative number. Now how much do you need to add to get to zero? Let's do it stepwise:
1000:0010 x +
0000:0001 1 =
----------------
1000:0011 (x+1)
1000:0011 (x+1) +
0000:0001 1 =
----------------
1000:0100 (x+2)
Lets do bigger steps. Just add 1s where we have zeros, but first we go back to x:
1000:0010 x +
0111:1101 y =
--------------
1111:1111
Now there is the turning point: we add another 1, and get zero (plus overflow)
1111:1111 (x + y) +
0000:0001 1
---------
0000:0000 0
If (x+y) + 1 = 0, x+y = -1. A minus 1 is, interestingly, not just the same as 1 (0000:0001) with a 'negative-flag' set ('1000:0001'), but looks completely different. However, the first position always tells you the sign: 1 always indicates negative.
But what did we add before?
0111:1101 y = ?
It doesn't have a 1 at the first position, so it is a positive value. We know how to deconstruct that?
..f:8421 Position of value (1, 2, 4, 8, 16=f, 32, 64 in opposite direction)
0111:1101 y = ?
..f 84 1 = 1+4+8+16+32+64= 125
And now it's clear: x+125 = -1 => x = -126
You may imagine the values, organized in a circle, with the 0 at the top (high noon) and positive values arranged like on a clock from 0 to 5 (but to 127), and the turning point at the bottom (127 + 1 => -128 [sic!].) Now you can go on clockwise, adding 1 leads to -127, -126, -125, ... -3, -2, -1 (at 11 o'clock) and finally 0 at the top again.
For bigger numbers (small, int, long) take bigger clocks, with the zero always on top, the maximum and minimum always on bottom. But even a byte is much too big, to make a picture, so I made one of a nibble, a half-byte:
You can easily fill the holes in the picture, it's trivial!
Btw.: the whole thing isn't called casting. Casting is only used between Objects. If you have something, which is in real a subtype:
Object o = new String ("casting or not?");
this is just an assignment, since a String is (always) an Object. No casting involved.
String s = (String) o;
This is a casting. To the more specific type. Not every object is a String. There is a small relationship to integer promotion, since every byte can be lossless transformed to long, but not every long to byte. However, even Byte and Long, the Object-types, aren't inherited from each other.
You just don't get a warning, for
byte s = (byte) 42;
long o = s; // no problem, no warning
byte b = (byte) o; // written like casting