why Integer.MAX_VALUE + 1 == Integer.MIN_VALUE?
Solution 1
Because the integer overflows. When it overflows, the next value is Integer.MIN_VALUE
. Relevant JLS
If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values.
Solution 2
The integer storage gets overflowed and that is not indicated in any way, as stated in JSL 3rd Ed.:
The built-in integer operators do not indicate overflow or underflow in any way. Integer operators can throw a
NullPointerException
if unboxing conversion (§5.1.8) of a null reference is required. Other than that, the only integer operators that can throw an exception (§11) are the integer divide operator/
(§15.17.2) and the integer remainder operator%
(§15.17.3), which throw anArithmeticException
if the right-hand operand is zero, and the increment and decrement operators++
(§15.15.1, §15.15.2) and--
(§15.14.3, §15.14.2), which can throw anOutOfMemoryError
if boxing conversion (§5.1.7) is required and there is not sufficient memory available to perform the conversion.
Example in a 4-bits storage:
MAX_INT: 0111 (7)
MIN_INT: 1000 (-8)
MAX_INT + 1:
0111+
0001
----
1000
Solution 3
You must understand how integer values are represented in binary form, and how binary addition works. Java uses a representation called two's complement, in which the first bit of the number represents its sign. Whenever you add 1 to the largest java Integer, which has a bit sign of 0, then its bit sign becomes 1 and the number becomes negative.
This links explains with more details: http://www.cs.grinnell.edu/~rebelsky/Espresso/Readings/binary.html#integers-in-java
--
The Java Language Specification treats this behavior here: http://docs.oracle.com/javase/specs/jls/se6/html/expressions.html#15.18.2
If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values.
Which means that you can rely on this behavior.
Solution 4
On most processors, the arithmetic instructions have no mode to fault on an overflow. They set a flag that must be checked. That's an extra instruction so probably slower. In order for the language implementations to be as fast as possible, the languages are frequently specified to ignore the error and continue. For Java the behaviour is specified in the JLS. For C, the language does not specify the behaviour, but modern processors will behave as Java.
I believe there are proposals for (awkward) Java SE 8 libraries to throw on overflow, as well as unsigned operations. A behaviour, I believe popular in the DSP world, is clamp the values at the maximums, so Integer.MAX_VALUE + 1 == Integer.MAX_VALUE
[not Java].
I'm sure future languages will use arbitrary precision ints, but not for a while yet. Requires more expensive compiler design to run quickly.
Solution 5
The same reason why the date changes when you cross the international date line: there's a discontinuity there. It's built into the nature of binary addition.
Oleg Mikheev
Java professional with over 15 years of experience and financial applications background.
Updated on April 15, 2021Comments
-
Oleg Mikheev about 3 years
System.out.println(Integer.MAX_VALUE + 1 == Integer.MIN_VALUE);
is true.
I understand that integer in Java is 32 bit and can't go above 231-1, but I can't understand why adding 1 to its
MAX_VALUE
results inMIN_VALUE
and not in some kind of exception. Not mentioning something like transparent conversion to a bigger type, like Ruby does.Is this behavior specified somewhere? Can I rely on it?
-
bobanahalf over 5 yearsAll these answers, all addressing how int works, none of them answering the question: Why does it do that? Why doesn't it throw an exception? Is there some useful functionality gained by allowing Integer.MAX_VALUE + 1 == -2147483648?
-
inavda over 5 yearsThis is the only answer that legitimately responds to the actual question.
-
Stephen C about 3 yearsThe stuff about adding
byte
arithmetic is a bit misleading ... and not really relevant. Sincebyte
values are always promoted toint
(or a "larger" type) before performing any arithmetical operations on them, it doesn't help to talk about examples involvingbyte
to understand integer overflow behavior. -
Stephen C about 3 yearsIt is true that there is a discontinuity (or to put it another way, bounds on the range of
int
) and that this must be handled some way. But it does not follow that it must be handled this way. There are a number of of other ways to handle integer overflow ... at least in theory.