Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
262 views
in Technique[技术] by (71.8m points)

negative char Value JAVA

Why doe it happen the following:

char p = 0;
p--;
System.out.println(p);

result 65535

Why does not give it out a compilation error or a runtime Exception? I expected it as chars cannot be negative. Instead it starts back counting from upside down. Thanks in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Why does not give it out a compilation error or a runtime Exception?

Because the language specification mandates that arithmetic on primitive types is modulo 2^width, so -1 becomes 2^16-1 as a char.

In the section on integer operations, it is stated that

The built-in integer operators do not indicate overflow or underflow in any way.

so that forbids throwing an exception.

For the postfix-decrement operator used, specifically, its behaviour is specified in 15.14.3

Otherwise, the value 1 is subtracted from the value of the variable and the difference is stored back into the variable. Before the subtraction, binary numeric promotion (§5.6.2) is performed on the value 1 and the value of the variable. If necessary, the difference is narrowed by a narrowing primitive conversion (§5.1.3) and/or subjected to boxing conversion (§5.1.7) to the type of the variable before it is stored. The value of the postfix decrement expression is the value of the variable before the new value is stored.

The binary numeric promotion converts both, the value and 1, to int (since the type here is char), thus you have the intermediate result -1 as an int, then the narrowing primitive conversion is performed:

A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.

resulting in a char value of 0xFFFF (since Java specifies two's complement representation for its signed integer types, explicitly stated in the specification of unary minus):

For integer values, negation is the same as subtraction from zero. The Java programming language uses two's-complement representation for integers, and the range of two's-complement values is not symmetric, so negation of the maximum negative int or long results in that same maximum negative number. Overflow occurs in this case, but no exception is thrown. For all integer values x, -x equals (~x)+1.

For the general wrap-around behaviour for out-of-range results, as an example in the specification of the multiplication operator:

If an integer multiplication overflows, then the result is the low-order bits of the mathematical product as represented in some sufficiently large two's-complement format. As a result, if overflow occurs, then the sign of the result may not be the same as the sign of the mathematical product of the two operand values.

Similar phrases occur in the specification of integer addition, and subtraction is required to fulfill a - b == a + (-b), so the overflow behaviour follows.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...