据我所知,在Java中,没有未签名的数字,他们都在幕后用魔法签名来理解它。
所以,我对此感到困惑,这可能是我之前提到的那种让我不知所措的巫术。
private static int broadcast = 0xffffffff; //4294967295
我正在使用IntelliJ作为IDE,并且上面的声明工作正常。如果我用十进制#替换十六进制数字,我会抱怨数字太大。它是相同的数字,我错过了什么?
我如何使用它:
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
}
}
在IntelliJ中,还有另一个奇怪的例子就是这种行为。当我检查地址时,检查员显示正确的值和负值,正如我在下面的图片中用红色箭头突出显示的那样。使用Windows calc,我输入-84并转换为十六进制并收到FFF ... FAC。当我输入172时,我收到的只是AC ...为什么我得到相同的十六进制数,在最大的sig位置前面加1?
答案 0 :(得分:7)
这是在JLS section 3.10.1中指定的,它对十进制文字和其他基础的文字有不同的规则:
如果int类型的十进制文字大于
2147483648
(2 31 ),或者小数文字2147483648
出现在其他任何地方,那么这是一个编译时错误而不是一元减运算符的操作数(§15.15.4)。
VS
以下十六进制,八进制和二进制文字表示十进制值-1:
0xffff_ffff
,
0377_7777_7777
和
0b1111_1111_1111_1111_1111_1111_1111_1111
如果十六进制,八进制或二进制int文字不适合32位,则为编译时错误。
这就是编译器以这种方式运行的原因 - 它基本上符合规范。
至于为什么规范是写那样...我怀疑这是因为用非十进制基数写的常量通常用于比特掩码技术等 - 你真正关心的是值中的位而不是它所代表的整数的符号和大小。
答案 1 :(得分:4)
0xffffffff
是-1作为int(尽管4294967295是无符号的)。
根据您使用该值的方式,它可能无关紧要。例如,将值写入二进制文件或将其用作位掩码将写出相同的字节。
如果在java中,您需要实际使用值4294967295作为正数,则需要使用long。
private static long broadcast = 4294967295L;
请注意尾随“L”以将其标记为长。