I understand that, in Java, there are no unsigned numbers, they're all signed with wizardry behind the scenes to make sense of it.
So, I am puzzled by this, and it's probably that wizardry that I mentioned before that's eluding me.
private static int broadcast = 0xffffffff; //4294967295
I'm using IntelliJ for an IDE, and in that, the above statement works fine. If I replace the hex number with the decimal #, I get a complaint that the number is too large. It's the same number, what am I missing?
How I'm using it all:
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);
System.out.println(String.format("curAddr: %d, firstClassE: %d, broadcast: %d", curAddr, firstClassE, broadcast));
return (curAddr >= firstClassE && curAddr < broadcast) ? true : false;
}
public static void main(String[] args) throws UnknownHostException
{
String ip = "10.20.30.40";
InetAddress someIP = InetAddress.getByName(ip);
if (IsClassEAddress(someIP))
{
// Raise a flag
System.out.println("Class E IP address detected.");
}
// Output of program is:
// curAddr: 169090600, firstClassE: -268435456, broadcast: -1
}
}
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?
This is specified in JLS section 3.10.1, which has different rules for decimal literals and literals of other bases:
It is a compile-time error if a decimal literal of type int is larger than
2147483648
(231), or if the decimal literal2147483648
appears anywhere other than as the operand of the unary minus operator (ยง15.15.4).
vs
The following hexadecimal, octal, and binary literals represent the decimal value -1:
0xffff_ffff
,
0377_7777_7777
, and
0b1111_1111_1111_1111_1111_1111_1111_1111
It is a compile-time error if a hexadecimal, octal, or binary int literal does not fit in 32 bits.
So that's why the compiler is behaving that way - it's basically as per the spec.
As for why the specification was written that way... I suspect it's because constants written in non-decimal bases are usually there for bitmasking techniques and the like - where really you just care about the bits in the value rather than the sign and magnitude of the integer it represents.
See more on this question at Stackoverflow