为什么Integer.MIN_VALUE的负数给出相同的值?

Nag*_*ran 8 java operators bitwise-operators ones-complement

考虑下面的java代码.

Integer value = Integer.MIN_VALUE;
System.out.println(value);

value = -value;
System.out.println(value);
Run Code Online (Sandbox Code Playgroud)

产量

-2147483648
-2147483648
Run Code Online (Sandbox Code Playgroud)

价值的负值如何产生Integer.MIN_VALUE相同的价值?

但结果不能是2147483648因为java中Integer的最大值是2147483647.

但想知道为什么-2147483648?内部发生了什么样的按位操作?

Kon*_*kov 14

当你否定-2147483648,它解析为2147483648,这超过了Integer.MAX_VALUE1.然后值Integer.MIN_VALUE再次溢出.

来自JLS:

整数类型是byte,short,int和long,其值为8位,16位,32位和64位带符号的二进制补码整数.

因此,对整数执行的每个一元运算实际上都将应用于数字的二进制补码表示.当Integer.MAX_VALUE达到它时,它将由一个前导0和31 1位组成.添加1会使它成为带前导1和后跟31 0的数字,这实际上是两个补码表示Integer.MIN_VALUE.

  • `当达到 Integer.MAX_VALUE 时,它将由 32 个 1 位组成。加 1 会使其成为 33 位数字,前导 1,尾随 0。` - 你搞错了。Integer.MAX_VALUE 是 0 后跟 31 个 1 位。加 1 会得到 1 后跟 31 个 0 位,这是 Integer.MIN_VALUE 的二进制补码表示形式 (2认同)

das*_*ght 13

内部发生了什么样的按位操作?

Java使用带符号数的二进制补码表示.因此,符号操作的变化包括两个步骤:

  1. 反转原始值的位,和
  2. 添加1到结果.

2147483648的代表如下:

10000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

反转它会产生

01111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)

添加1使它再次成为相同的数字,即

10000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

由于整数溢出.