负字符值 JAVA
为什么会这样:
char p = 0;
p--;
System.out.println(p);
结果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.
推荐答案
为什么不给它一个编译错误或运行时异常?
Why does not give it out a compilation error or a runtime Exception?
因为语言规范要求原始类型的算术是模 2^width
,所以 -1
变成 2^16-1
为一个 char
.
Because the language specification mandates that arithmetic on primitive types is modulo 2^width
, so -1
becomes 2^16-1
as a char
.
在 整数运算部分,据说
内置的整数运算符不会以任何方式指示上溢或下溢.
The built-in integer operators do not indicate overflow or underflow in any way.
这样就禁止抛出异常.
对于使用的后缀减量运算符,具体而言,其行为在 15.14.3
For the postfix-decrement operator used, specifically, its behaviour is specified in 15.14.3
否则,从变量的值中减去值 1,并将差值存储回变量中.在减法之前,对值 1 和变量的值执行二进制数字提升(第 5.6.2 节).如有必要,通过缩小原始转换(第 5.1.3 节)和/或在存储变量之前对其类型进行装箱转换(第 5.1.7 节)来缩小差异.后缀递减表达式的值是变量在新值被存储之前的值.
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.
二进制数字提升将值和 1 都转换为 int
(因为这里的类型是 char
),因此您有中间结果 -1
为int
,则进行窄化原语转换:
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:
有符号整数到整数类型 T 的窄化转换只会丢弃除 n 个最低位之外的所有位,其中 n 是用于表示类型 T 的位数.除了可能丢失有关数值,这可能会导致结果值的符号与输入值的符号不同.
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.
导致 0xFFFF
的 char
值(因为 Java 为其有符号整数类型指定二进制补码表示,在 一元减号):
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):
对于整数值,取反与从零减法相同.Java 编程语言对整数使用二进制补码表示,二进制补码值的范围不是对称的,因此最大负 int 或 long 的取反会产生相同的最大负数.这种情况下会发生溢出,但不会抛出异常.对于所有整数值 x,-x 等于 (~x)+1.
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.
在整数加法的规范中出现类似的短语,需要减法来满足a - b == a + (-b)
,所以溢出行为如下.
Similar phrases occur in the specification of integer addition, and subtraction is required to fulfill a - b == a + (-b)
, so the overflow behaviour follows.
相关文章