Question

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
Was it helpful?

Solution

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.

OTHER TIPS

ANDing a byte with an int first sign-extends the byte to int, and then the AND happens.

That means, in this case, that the bytes are converted to ints with sign extension, but then the value to AND with has been chosen such that the extended sign bits are masked away.

So the result is as though you zero-extended the bytes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top