i的值(i == -i && i!= 0)在Java中返回true

Sun*_*nny 100 java

我有以下if情况.

if (i == -i && i != 0)
Run Code Online (Sandbox Code Playgroud)

在Java中,这个条件i会返回什么值true?

我无法想到在Java 中i考虑两个补码表示法的任何这样的价值.

我还希望得到这种情况的任何答案的代数证明(在Java的上下文中)?

Den*_*ret 125

它的唯一int价值在于 Integer.MIN_VALUE.

这是因为整数被使用二者的补充方式否定了.

运用

System.out.println(Integer.toBinaryString(Integer.MIN_VALUE));
Run Code Online (Sandbox Code Playgroud)

你看Integer.MIN_VALUE是的

10000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

取负值时,首先交换完成0和1,这使

01111111111111111111111111111111
Run Code Online (Sandbox Code Playgroud)

并通过添加1,给出

10000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)

正如您在我给出的链接中所看到的,维基百科提到了最负数的问题,并指出它是唯一的例外:

二进制补码中最负的数字有时称为"奇数",因为它是唯一的例外.

当然,Long.Min_Value如果将其存储在long变量中,则会出现相同的现象.

请注意,这仅仅是由于对Java中的int的二进制存储进行了选择.另一个(坏的)解决方案可能是通过简单地改变最重要的位并让其他位保持不变来否定,这可以避免MIN_VALUE的这个问题,但是会产生2个不同的0值和复杂的二进制算术(你会怎么做?例如增加?).

  • 值得注意的是,早期的二进制计算机确实使用了上一段中描述的整数的符号和幅度实现; 和IEE754浮点数一样.http://en.wikipedia.org/wiki/Signed_number_representations#Sign-and-magnitude_method (2认同)
  • 值得一提的是它[在Java Spec上记录](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.15.4):"Java编程语言使用整数的二进制补码表示,并且二进制补码值的范围不对称,因此否定最大负数int或long会导致相同的最大负数." (2认同)

Ste*_*n C 25

你正在寻找的价值是Integer.MIN_VALUE.


我也很想得到这种情况的任何答案的代数证明(在java的上下文中)?

这是Stack Exchange的主题.但是你可以从Java整数的定义开始(JLS 4.2)

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

和

"积分类型的值在以下范围内是整数...对于int,从-2147483648到2147483647,包括"

以及Java一元' - '运算符的定义(JLS 15.15.4):

"对于整数值,否定与从零减法相同.Java编程语言对整数使用二进制补码表示,并且二进制补码值的范围不对称,因此否定最大负数int或long会导致相同的最大负数.在这种情况下发生溢出,但没有抛出异常.对于所有整数值x,-x等于(~x)+1.

  • _Long.MIN_VALUE_也是. (3认同)
  • @Sunny它不能太难证明.在整数范围内,所有正数都具有负对应(所以`i!= -i`).这留下了两个数字:`0`和`Integer.MIN_VALUE`.因为if中的`i!= 0`,只剩下'MIN_VALUE`. (2认同)

Pet*_*rey 18

除了迄今给出的答案之外......

总共有四个值

int i = Integer.MIN_VALUE;
long i = Long.MIN_VALUE;
Integer i = Integer.valueOf(Integer.MIN_VALUE);
Long i = Long.valueOf(Long.MIN_VALUE);
Run Code Online (Sandbox Code Playgroud)

包装的值将被解包,因此对于此表达式它们也是如此.

注意:Math.abs文档.

public static int abs(int a)

返回int值的绝对值.如果参数不是负数,则返回参数.如果参数为负数,则返回参数的否定.

请注意,如果参数等于Integer.MIN_VALUE的值,即最负的可表示的int值,则结果是相同的值,即负值.

和

公共静态长abs(长a)

返回long值的绝对值.如果参数不是负数,则返回参数.如果参数为负数,则返回参数的否定.

请注意,如果参数等于Long.MIN_VALUE(最负的可表示长值)的值,则结果是相同的值,即负值.

令人惊讶的是,Math.abs可能会返回一个负数.这是因为a)在这些情况下-MIN_VALUE没有正值b)执行-溢出计算结果.

还有什么兴趣是为什么没有Byte.MIN_VALUE,Short.MIN_VALUE不这样做.这是因为将-类型更改int为这些并因此没有溢出.

Character.MIN_VALUE没有问题,因为它是0.

Float.MIN_VALUE和Double.MIN_VALUE具有不同的含义.这些是大于零的最小可表示值.因此,它们具有有效的负值,而不是它们本身.


Mar*_*k M 14

就像其他人提到的那样,这只能满足Integer.MIN_VALUE.至于证据,让我提供一个比二进制更容易理解的解释(虽然它仍然根植于此).

需要注意的是Integer.MIN_VALUE等于-2^31或-2147483648和Integer.MAX_VALUE等于2^31-1或2147483647.-Integer.MIN_VALUE是2^31,现在对于整数来说太大了(因为它已经过去MAX_VALUE)因此导致整数溢出,Integer.MIN_VALUE再次出现.它是唯一一个执行此操作的Integer,因为MIN_VALUE除了0之外,它是唯一没有负等价的数字.

  • @dystroy实际上我正在寻找一些解释,根据Mark,在int范围内没有+2147483648这样的数字,所以首先怀疑应该是0以外的这个数字.范围是-2 ^ n到2 ^ n-1.因此-2 ^ n没有正对应物.这只是另一个可能的int值. (2认同)

Yve*_*ust 6

初步的代数证明,使用modulo 2^32算术:

i == -i可以改写为2 * i == 0(i双面添加),或i << 1 == 0.

该等式具有两种形式的解i == 0 >> 1,即通过在左侧或左侧移位0b而10000000000000000000000000000000b获得.01

解决方案i == 0被排除在外,仍有解决方案i == 100000000000000000000000000000000b.