为什么整数。MAX_VALUE+1==整数。MIN_VALUE?
-
29-10-2019 - |
题
System.out.println(Integer.MAX_VALUE + 1 == Integer.MIN_VALUE);
是真实的。
我的理解是,整数是32位和不能去上述231-1,但我不能理解为什么加1到它 MAX_VALUE
结果在 MIN_VALUE
而不是在某种例外。没提到什么样的透明转换为一个更大的类型,就像的红宝石做的。
是这个行为指定的地方吗?我可以依靠?
解决方案
因为整数溢出。当它溢出时,下一个值是Integer.MIN_VALUE
。相关的JLS
如果整数加法溢出,则结果为数学和的低阶位,以某种足够大的二进制补码格式表示。如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同。
其他提示
在整数储存获得溢出和 这是不是表明在任何方式,如在桑妮3rd Ed.:
内置在整数运营者没有表明溢的溢出或以任何方式。整型运营商可以扔掉一个
NullPointerException
如果拆箱的转换 (§5.1.8) 一个空基准是必需的。除此之外,只有整数经营者,可以把一个异常 (§11) 是整数划分的操作者/
(§15.17.2) 和整数余操作员%
(§15.17.3), ,它扔一个ArithmeticException
如果右的操作数为零,并且增加和减少运营商++
(§15.15.1, §15.15.2)和--
(§15.14.3, §15.14.2),这可以扔掉一个OutOfMemoryError
如果拳击转换 (§5.1.7) 是必需的,并没有足够的存储器可用来执行转换。
例如在4位存储:
MAX_INT: 0111 (7)
MIN_INT: 1000 (-8)
MAX_INT+1:
0111+
0001
----
1000
您必须了解整数值如何以二进制形式表示以及二进制加法的工作方式。 Java使用称为二进制补码的表示形式,其中数字的第一位表示其符号。每当将1加到最大Java Integer(位符号为0)时,它的位符号就变为1,并且数字变为负数。
此链接将详细说明: http://www.cs.grinnell.edu/~rebelsky/Espresso/Readings/binary.html#integers-in-java
-
Java语言规范在此处处理此行为: http://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.18.2
如果整数加法溢出,则结果是数学和的低阶位,以某种足够大的二进制补码格式表示。如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同。
这意味着您可以依靠这种行为。
在大多数处理器上,算术指令没有模式可以在溢出时出错。他们设置了一个必须检查的标志。那是一条额外的指令,因此可能会更慢。为了使语言实现尽可能快,经常指定语言以忽略错误并继续。对于Java,该行为在 JLS 中指定。对于C语言,该语言未指定行为,但是现代处理器将表现为Java。
我相信有一些建议(笨拙的)Java SE 8库会引发溢出以及未签名的操作。我相信在DSP世界中很流行的一种行为是将值限制在最大值,因此生成了基因代码标签[不是Java]。
我确定将来的语言将使用任意精度的int,但暂时不会使用。需要更昂贵的编译器设计才能快速运行。
您越过国际日期变更线时日期也会更改的原因相同:那里不连续。它是二进制加法的本质。
这是一个与整数相关的事实,整数表示为二进制补码。当您将2的补数的最大值加1时,您将获得最小值。坦白地说,所有整数在Java出现之前都以这种方式表现,而更改Java语言的这种行为会增加整数数学的开销,并使来自其他语言的程序员感到困惑。
当将3
(在二进制11
中)添加到1(在binary1
中)时,您必须从右开始将所有二进制0
更改为0
(在binary1
中),直到得到0,然后应将其更改为1
。由于Integer.MAX_VALUE
的所有位置都充满了1
,因此仅保留0
。
Cause overflow and two-compliant nature count goes on "second loop", we was on far most right position 2147483647 and after summing 1, we appeared at far most left position -2147483648, next incrementing goes -2147483647, -2147483646, -2147483645, ... and so forth to the far most right again and on and on, its nature of summing machine on this bit depth.
Some examples:
int a = 2147483647;
System.out.println(a);
gives: 2147483647
System.out.println(a+1);
gives: -2147483648 (cause overflow and two-compliant nature count goes on "second loop", we was on far most right position 2147483647 and after summing 1, we appeared at far most left position -2147483648, next incrementing goes -2147483648, -2147483647, -2147483646, ... and so fores to the far most right again and on and on, its nature of summing machine on this bit depth)
System.out.println(2-a);
gives:-2147483645 (-2147483647+2 seems mathematical logical)
System.out.println(-2-a);
gives: 2147483647 (-2147483647-1 -> -2147483648, -2147483648-1 -> 2147483647 some loop described in previous answers)
System.out.println(2*a);
gives: -2 (2147483647+2147483647 -> -2147483648+2147483646 again mathematical logical)
System.out.println(4*a);
gives: -4 (2147483647+2147483647+2147483647+2147483647 -> -2147483648+2147483646+2147483647+2147483647 -> -2-2 (according to last answer) -> -4)`