I have this code:
package com.company;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Main {
private final static int broadcast = 0xffffffff; //4294967295, or 255.255.255.255
private final static int firstClassE = 0xf0000000; //4026531840, or 240.0.0.0
public static int GetIntInetAddress(InetAddress toConvert)
{
final byte[] addr = toConvert.getAddress();
final int ipAddr =
((addr[0] & 0xFF) << (3 * 8)) +
((addr[1] & 0xFF) << (2 * 8)) +
((addr[2] & 0xFF) << (1 * 8)) +
(addr[3] & 0xFF);
return ipAddr;
}
public static Boolean IsClassEAddress(InetAddress address)
{
int curAddr = GetIntInetAddress(address);
Boolean test1 = curAddr >= firstClassE;
Boolean test2 = curAddr < broadcast;
System.out.println(String.format("\ncurAddr: %s, firstClassE: 240.0.0.0, broadcast: 255.255.255.255", address.getHostAddress()));
System.out.println(String.format("curAddr: %d, firstClassE: %d, broadcast: %d, curAddr >= firstClassE: %s, curAddr < broadcast: %s",
curAddr, firstClassE, broadcast, test1 ? "true" : "false", test2 ? "true" : "false"));
return (test1 && test2) ? true : false;
}
public static void main(String[] args) throws UnknownHostException
{
if (IsClassEAddress(InetAddress.getByName("1.0.0.0")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("250.0.0.0")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("239.255.255.255")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("240.0.0.0")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("240.0.0.1")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
if (IsClassEAddress(InetAddress.getByName("255.255.255.255")))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
}
}
Which produces the following output:
curAddr: 1.0.0.0, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: 16777216, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: false
curAddr: 250.0.0.0, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -100663296, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: true
Class E IP address detected.
curAddr: 239.255.255.255, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -268435457, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: false, curAddr < broadcast: true
curAddr: 240.0.0.0, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -268435456, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: true
Class E IP address detected.
curAddr: 240.0.0.1, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -268435455, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: true
Class E IP address detected.
curAddr: 255.255.255.255, firstClassE: 240.0.0.0, broadcast: 255.255.255.255
curAddr: -1, firstClassE: -268435456, broadcast: -1, curAddr >= firstClassE: true, curAddr < broadcast: false
What I am not understanding is why the numbers and comparisons are not what I expect them to be, yet the code produces the results I want. I gather it's the whole two's complement thing, which I just don't "get" for some reason. Mechanically, I know it (two's complement) is flipping bits and adding 1 but what I don't get is, why are my comparisons working properly if some of the numbers are inverted?
For example, in the first check for IP 1.0.0.0, the int value 16777216 is checked to see if it's smaller than the int value for 255.255.255.255, which is -1. The result is false, but the broadcast IP, when converted to an int, is obviously larger, not smaller, than the IP for 1.0.0.0. Likewise, the check for 1.0.0.0 being at least, or higher than, 240.0.0.0 returns true, when we know that clearly isn't the case.
I've checked the boundary cases and everything is working... I just don't understand why it is (and I wrote the code, so go figure!). If there is a more clear method of determining if an IP fals within a range, I would like to explore that as my way must not be making sense, despite working (or does it?)
In IntelliJ, there's another strange example of this behaviour. When I examine an address, the inspector is showing both the proper value and the negative value, as I've highlighted with red arrows in the pic below. Using Windows calc, I put in -84 and converted to hex and received FFF...FAC. When I put in 172, I received just AC... why do I get the same hex number, just preceeded by a 1 in the most sig position?

UPDATE:
Thanks for all the patient discussion and great answers! I think I get the mechanics of the thing, but still grappling with the subtleties of usage. :) Cheers!
1.0.0.0in binary is0x01000000and255.255.255.255is0xFFFFFFFF. The first value represents16777216and the second value represents-1. You can't change this by saying you don't "get" two's-complement. It just is. - Jim Garrisonlonginstead of anint, and then everything will be positive. - ajbreturn (test1 && test2) ? true : false;trololo - kajacx0xFFFFFFFFis "larger" than0x01000000ONLY if the comparison is unsigned. As a Javaintwhich is signed, it is smaller. - Jim Garrison