Java Int Confusion

时间:2014-06-17 13:36:26

标签: java int

据我所知,在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?

Another strange example I've seen

2 个答案:

答案 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”以将其标记为长。