doubt with range of int variable
i have a doubt with the range of int value
int x=2147483647; /*NO Error--this number is the maximum range
of int value no error*/
int y=2147483648; /*Error--one more than the
maximum range of int*/
int z=2147483647+1; /*No Error even though it is one more
开发者_如何转开发 than the maximum range value*/
why ?
Here is an explanation in terms of the Java Language Specification.
The section on integer literals (JLS 3.10.1) says this:
The largest decimal literal of type int is
2147483648
(231). All decimal literals from0
to2147483647
may appear anywhere an int literal may appear, but the literal2147483648
may appear only as the operand of the unary negation operator-
.
So ...
The first statement is an assignment of a legal integer literal value. No compilation error.
The second statement is a compilation error because
2147483648
is not preceded by the unary negation operator.The third statement does not contain an integer literal that is out-of-range, so it is not a compilation error from that perspective.
Instead, the third statement is a binary addition expression as described in JLS 15.18.2. This states the following about the integer case:
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.
Thus, 2147483647 + 1
overflows and wraps around to -2147483648
.
@Peter Lawrey's suggests (flippantly?) that the third statement could be "rewritten by the compiler" as +2147483648
, resulting in a compilation error.
This is not correct.
There is nothing in the JLS that says that a constant expression can have a different meaning to a non-constant expression. On the contrary, in cases like 1 / 0
the JLS flips things around and says that the expression is NOT a constant expression BECAUSE it terminates abnormally. (It is in JLS 15.28)
The JLS tries very hard to avoid cases where some Java construct means different things, depending on the compiler. For instance, it is very particular about the "definite assignment" rules, to avoid the case where only a smart compiler can deduce that variable is always initialized before it is used. This is a GOOD THING from the perspective of code portability.
The only significant area where there is "wiggle room" for compiler implementers to do platform specific things is in the areas of concurrency and the Java memory model. And there is a sound pragmatic reason for that - to allow multi-threaded Java applications to run fast on multi-core / multi-processor hardware.
int
ranges from Integer.MIN_VALUE
(-2147483648) to Integer.MAX_VALUE
(2147483647).
However, only int
literals are checked against the range.
Java does not check that any given constant value expression fits within the range.
Calculations are "allowed" to pass those boundaries, but that will result in an overflow (i.e. only the lower bits of the resulting value will be stored). Therefore, the calculation 2147483647 + 1
is well-defined within int
calculations, and it's -2147483648.
Because the third one is called integer overflow. You are doing computations and you overflow. The other ones are just constants.
The first two cases seem obvious. The third case will silently overflow. So in such cases you should always handle that in your calling code.
Because
int z=2147483647+1;
would be overflowed , which isn't equal to 2147483648
the third expression is an int-based addition, hence it will cast the result to a value within int's range.
The range for int
is Integer.MIN_VALUE
to Integer.MAX_VALUE
. Java sliently overflows so the result of a calcuation is not detected by the compiler. (But might be detected by your IDE)
One of the most surprising overflow operations is -Integer.MIN_VALUE
精彩评论