繁体   English   中英

负字符值 JAVA

[英]negative char Value JAVA

为什么会发生以下情况:

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

结果65535

为什么不给出编译错误或运行时异常? 我预计它是因为字符不能为负。 相反,它从倒过来开始倒数。 提前致谢。

为什么不给出编译错误或运行时异常?

因为语言规范要求原始类型的算术是模2^width ,所以-1变成2^16-1作为char

整数运算部分中,指出

内置整数运算符不以任何方式指示上溢或下溢。

所以禁止抛出异常。

对于所使用的后缀递减运算符,具体而言,其行为在15.14.3 中指定

否则,从变量的值中减去值 1,并将差值存储回变量中。 在减法之前,对值 1 和变量的值执行二进制数字提升(第 5.6.2 节)。 如有必要,在存储变量之前,通过缩小原始转换(第 5.1.3 节)和/或进行装箱转换(第 5.1.7 节)来缩小差异。 后缀递减表达式的值是存储新值之前变量的值。

二进制数字提升将 value 和 1 都转换为int (因为这里的类型是char ),因此您将中间结果-1作为int ,然后执行缩小原语转换:

有符号整数到整数类型 T 的缩窄转换只会丢弃除 n 个最低位以外的所有位,其中 n 是用于表示类型 T 的位数。此外可能会丢失有关数值大小的信息,这可能会导致结果值的符号与输入值的符号不同。

导致char值为0xFFFF (因为 Java 为其有符号整数类型指定了二进制补码表示,在一元减号的规范中明确说明):

对于整数值,否定与从零减法相同。 Java 编程语言对 integers 使用二进制补码表示,并且二进制补码值的范围不对称,因此最大负 int 或 long 的否定会导致相同的最大负数。 在这种情况下会发生溢出,但不会抛出异常。 对于所有整数值 x,-x 等于 (~x)+1。

对于超出范围结果的一般环绕行为,作为乘法运算符规范中的示例:

如果整数乘法溢出,则结果是数学乘积的低位,以某种足够大的二进制补码格式表示。 因此,如果发生溢出,则结果的符号可能与两个操作数值的数学乘积的符号不同。

类似的短语出现在整数加法的规范中,需要减法来满足a - b == a + (-b) ,因此溢出行为如下。

因为这就是 Java 语言的定义方式。 运行时不会检查每个操作的边界(可能是因为它会非常昂贵)。 它只是溢出或下溢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM