Search code examples
javastringbinaryinetaddress

Why the ip address value is and with int 255


I have a simple program to find my IP address and convert it to a String. Why is the b[i] value with (int)255 below?

public class FirstSocketProgramming {  

 public static void main (String arg[]){  

  InetAddress local = null;  

  try {  

   local = InetAddress.getLocalHost();  

  } catch (UnknownHostException e){  

   System.err.println   

      ("Identity Crisis!");  

   System.exit(0);  

  }  

 byte[] b = local.getAddress();  

System.out.println (b.toString());  
System.out.println (b.length);  
 String strAddress="";  

 for (int i = 0; i < b.length; i++)  

   strAddress += ((int)255&b[i]) + ".";  

 System.out.println ("Local = " + strAddress);  

 }  

}

Solution

  • byte data type is based on Two's complement binary signed number representation with a value range from -128 to +127.

    Positive values from 0 to 127 have it's most significant bit equal to 0 representing +. Here binary representation is the same as it's numeric value, for example byte 00000100 = int 4

    Negative values from -128 to -1 have it's most significant bit equal to 1 representing - However in negative range, Two's complement binary representation is NOT the same as it's numeric value, for example you would expect byte 10000100 to be equal to int 132, but is actually -124. Simply casting a byte to int won't help.

    Casting just widens 1 byte to 4 btytes, 10000100 ==> 11111111111111111111111110000100 which is equal to -124, not 132, because int data type is also based on Two's complement. Casting byte into int is a step in the right direction, however you also need to get rid of all these ones in front. 255&b[i] trick achieves that.

    This is what happens in 255&b[i]:
    According to conversion rules defined in the the JLS & bitwise operator first converts it's operands to int, which means 255&b[i] is the same as ((int)255)&((int)b[i]). When byte is cast to int it just gets wider:

    10000100 = byte -124 ==> 11111111111111111111111110000100 = int -124

    Then bitwise AND is performed.

    11111111111111111111111110000100 = int -124 
    &
    00000000000000000000000011111111 = int 255
    --------------------------------
    00000000000000000000000010000100 = int 132
    

    Final result is an int 132