The code below displays a number stored as a Java byte value as hex, and in signed and unsigned representation. That might not be the correct wording. What I mean is, these numbers could be C style 1 byte unsigned char values. If I am interpreting these values (just so happens to be Java here but could be using any signed type in any language) then if the 'number' overflows into using the sign bit then the number will appear negative. But I can print as it would appear in unsigned interpretation by ANDing with 0xFF.
I understand how AND works but I can't understand how the ANDing presents as unsigned. Can someone please explain?
public class understand_casting {
public static String printbinary(byte val) {
int displayMask = 1 << 7;
String str = new String();
for(int bit = 1; bit <= 8; ++bit) {
str += (val & displayMask) == 0 ? '0' : '1';
val <<= 1; //shift one to left
}
return str;
}
public static void main(String[] args) {
System.out.printf("0x50=%s, as int=%d, as unsigned int=%d\n", printbinary((byte)0x50), (byte)0x50, ((byte)0x50 & 0xFF));
System.out.printf("0x88=%s, as int=%d, as unsigned int=%d\n", printbinary((byte)0x88),(byte)0x88, ((byte)0x88 & 0xFF));
System.out.printf("0x3E=%s, as int=%d, as unsigned int=%d\n", printbinary((byte)0x3E),(byte)0x3E, ((byte)0x3E & 0xFF));
System.out.printf("0xB7=%s, as int=%d, as unsigned int=%d\n", printbinary((byte)0xB7), (byte)0xB7, ((byte)0xB7 & 0xFF));
}
}
I get this output:
0x50=01010000, as int=80, as unsigned int=80
0x88=10001000, as int=-120, as unsigned int=136
0x3E=00111110, as int=62, as unsigned int=62
0xB7=10110111, as int=-73, as unsigned int=183
As you might expect the binary of int
1 is
0000 0000 0000 0000 0000 0000 0000 0001
according to twos complement, you negate a number by inverting it and adding 1, so the binary of the signed int
-1 in twos complement looks like
1111 1111 1111 1111 1111 1111 1111 1111
Any negative number is going to have the high bit set, while any positive number is going to have the high bit zero.
For example, 0xff looks like and has a long string of 0's to the left
0000 0000 0000 0000 0000 0000 1111 1111
while -0xff looks like
1111 1111 1111 1111 1111 1111 0000 0001
When you mask using &
you keep only the 1 bits that are present in both, so -2 & 0xff looks like
1111 1111 1111 1111 1111 1111 1111 1110 | -2
0000 0000 0000 0000 0000 0000 1111 1111 | 0xff
0000 0000 0000 0000 0000 0000 1111 1110 | -2 & 0xff = 0xfe
ANDing with a positive value yields a positive value because the resulting high bit is always 0.