【问题标题】:Why does this code print two negative numbers? [duplicate]为什么这段代码打印两个负数? [复制]
【发布时间】:2017-10-14 13:30:01
【问题描述】:
int a = Integer.MIN_VALUE;
int b = -a;
System.out.println("a = "+a + " | b = "+b);

结果:

a = -2147483648 | b = -2147483648

我希望 b 是一个正数。

【问题讨论】:

  • 因为最大正数小一。它考虑了 0,并且正数和负数一样多
  • 一个整数的最大值是 2147483647,所以它会循环回到最小值。如果您将 1 添加到 a 之前,它应该可以工作,然后将值分配给 b
  • 这是一个二进制补码的怪癖,基本上。考虑byte 类型,其值从-128 到127...如果您有一个字节x 的值为-128,那么-x 的值是多少?
  • 每个程序员都必须知道补码算法。此外,文档中还介绍了数字类型的格式和范围。
  • 如果您期望 b 是一个正数,什么您期望的正数,以及 为什么您期望它,给定Integer.MAX_VALUE 是 2147483647?

标签: java


【解决方案1】:

更改Integer.MIN_VALUE 的符号会产生溢出;你看到了结果。

【讨论】:

    【解决方案2】:

    如果你曾经做过这样的事情:

    int a = Integer.MAX_VALUE;
    a++;
    System.out.println(a);
    

    您会知道,当某些内容超过数据类型的最大值时,它会循环回到其最小值。而当它小于最小值时,它会循环回到最大值。

    同样的事情发生在这里。

    否定 int 的最小值在数学上会给我们 2147483648,但因为它比最大值大一。它再次循环回到最小值,即-2147483648。

    有趣的事实:否定基本上是将每个位从 0 转换为 1,从 1 转换为 0,然后加一。尝试对 100000000000000000000000000000000 执行此操作,这就是 int 的最小值在二进制中的样子。

    【讨论】:

      【解决方案3】:

      对于底层的二进制解释,这是因为有符号整数是用Two's complement存储的。

      所以,二进制中最大的负数是 1000 0000。要反转符号,你翻转所有位,然后加一个......

      1000 0000 => 0111 1111 + 1 = 1000 0000

      你又回到了你开始的地方!

      和上面的例子一样,一个字节(8位)的有符号范围是-128到127,所以-(-128)是128,是127的1,所以它溢出回到-128。

      那为什么要用补码呢? 1 - 1 变为 1 + (-1) 或 0001 + 1111 = 0000。因此,通过将负数存储在二进制补码中,减法只需将第二个数字的二进制补码加在一起即可。 (这对机器来说比在算术逻辑单元 (ALU) 中添加减法电路更有效;因为它已经具有按位非和加法来进行二进制补码)。

      【讨论】:

        【解决方案4】:

        通常,当我们尝试为大于 int 类型最大值的 int 类型分配值时,它会再次从 int 的最小值开始环回,例如

        2147483648 -will become-> -2147483648
        2147483649 -will become-> -2147483647
        2147483650 -will become-> -2147483646
        

        a 的第一个语句值之后是-2147483648

        当你在做int b = -a; 通常b 应该有

        b = -a --> -(-2147483648) --> 2147483648
        

        但是 int 的最大正值是2147483647 并且21474836482147483647 大一,它将循环返回1 并变成-2147483648

        【讨论】:

          猜你喜欢
          • 2022-12-18
          • 2012-03-23
          • 2017-05-08
          • 2017-12-16
          • 1970-01-01
          • 2016-11-21
          • 1970-01-01
          • 2023-03-25
          • 1970-01-01
          相关资源
          最近更新 更多