【问题标题】:Java Integers Min_Value negative then compareJava Integers Min_Value 负数然后比较
【发布时间】:2012-09-21 17:13:05
【问题描述】:

我明天要考试,我看不懂我的书的解释,感谢帮助:

public class TestClass{
      public static void main(String[] args) throws Exception{
            int a = Integer.MIN_VALUE;
            int b = -a;
            System.out.println( a+ "   "+b);
      }
}

输出:-2147483648 -2147483648

为什么这会打印 2 个大小相同的负数而不是正数和负数?

【问题讨论】:

    标签: java variables integer negative-number


    【解决方案1】:

    因为静默整数溢出:Integer.MIN_VALUE-2^31Integer.MAX_VALUE2^31-1,所以 -Integer.MIN_VALUE2^31,即 Integer.MAX_VALUE + 1,根据定义对于整数来说太大了。于是就溢出了,变成了Integer.MIN_VALUE...

    您还可以检查:

    System.out.println(Integer.MAX_VALUE + 1);
    

    打印同样的东西。

    从技术上讲,结果由Java Language Specification #15.18.2 定义:

    如果整数加法溢出,则结果是数学和的低位,以一些足够大的二进制补码格式表示。如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同。

    【讨论】:

    • 啊,我的书给了我二进制的解释,我更喜欢这种我更容易理解的解释。非常感谢。
    • 实现此问题的另一种方法是使用Math.abs()Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
    【解决方案2】:

    基本上,因为Integer.MAX_VALUE实际上只有2147483647,所以-Integer.MIN_VALUE,也就是+2147483648,实际上溢出了整数内部二进制表示的容量。因此,结果“循环”回到Integer.MIN_VALUE,或-2147483648。

    如果你改为使用long b = -((long)a);,你会得到预期的结果。

    【讨论】:

      【解决方案3】:

      为了更清楚地展示这一点:

      Integer.MIN_VALUE is -2^31 = -2147483648
      Integer.MAX_VALUE is 2^31-1 = 2147483647 
      /*notice this is 1 less than the negative value above*/
      

      Integer.MAX_VALUE 不能接受2147483648。对于 Integer 来说,这个数字太大了,正好相差 1。这会导致数字在刻度上从最大值返回到最小值。

      【讨论】:

        【解决方案4】:

        固定数量的二进制位可以编码偶数个事物。这意味着你不能有一个完全以零为中心的序列,因为这需要一个对称的事物数量。在句子中间最接近零的方法是将其拆分为负数和非负数,或正数和非正数。正常的二进制补码编码是前者。所以 32 位的范围从 -2^31 到 2^31-1。零在序列的非负半部分,并且您有一个负数不能正确取反。

        【讨论】:

          猜你喜欢
          • 2012-09-14
          • 2016-01-18
          • 2015-02-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多