Search code examples
javabyteunsignedsigned

convert a java.net.InetAddress to a long


I would like to convert a java.net.InetAddress and I fight with the signed / unsigned problems. Such a pain.

I read convert from short to byte and viceversa in Java and Why byte b = (byte) 0xFF is equals to integer -1?

And as a result came up with:

     final byte [] pumpeIPAddressRaw =
        java.net.InetAddress.getByName (pumpeIPAddressName).getAddress ();

     final long pumpeIPAddress =
         ((pumpeIPAddressRaw [0] & 0xFF) << (3*8)) +
         ((pumpeIPAddressRaw [1] & 0xFF) << (2*8)) +
         ((pumpeIPAddressRaw [2] & 0xFF) << (1*8)) +
         (pumpeIPAddressRaw [3] &  0xFF);

     android.util.Log.i (
        Application.TAG, "LOG00120: Setzte Pumpen Addresse : " +
        pumpeIPAddress + ":" + pumpeIPPort);

And guess what the log still shows:

04-10 13:12:07.398 I/ch.XXXX.remote.Application(24452): LOG00120: Setzte Pumpen Addresse : -1063035647:27015

Does anybody know what I am still doing wrong?


Solution

  • & 0xff blocks sign extension during conversion from byte to int, but your expression also contains conversion from int to long and you need to block sign extension during this conversion as well:

    final long pumpeIPAddress =
          (((pumpeIPAddressRaw [0] & 0xFF) << (3*8)) + 
          ((pumpeIPAddressRaw [1] & 0xFF) << (2*8)) +
          ((pumpeIPAddressRaw [2] & 0xFF) << (1*8)) +
          (pumpeIPAddressRaw [3] &  0xFF)) & 0xffffffffl; 
    

    Alternatively, you can convert from byte to long in a single step, by marking the second operand of & 0xff operation as long using l suffix:

    final long pumpeIPAddress =
          ((pumpeIPAddressRaw [0] & 0xFFl) << (3*8)) + 
          ((pumpeIPAddressRaw [1] & 0xFFl) << (2*8)) +
          ((pumpeIPAddressRaw [2] & 0xFFl) << (1*8)) +
          (pumpeIPAddressRaw [3] &  0xFFl);