为什么byte的最大值加一,却没有溢出
Why the maximum value of byte plus one, but there is no overflow
class Overflowtest {
public static void main(String[] args) {
byte maxValue= Byte.MAX_VALUE;
System.out.println("maxValue of byte is "+maxValue);
System.out.println("add 1 to maxValue of byte is "+maxValue+(byte)2);
}
}
为什么我尝试maxValue+(byte)2
时没有发生溢出?
但如果我这样做,(byte)(maxValue+2)
,就会发生溢出。
在您的示例中,您将 127 添加到一个字符串,然后将 2 添加到一个字符串。
但是当你这样做时:
System.out.println(maxValue+(byte)2);
二元运算return一个整数。
正如其他人在解决括号后所说的那样,您可以打印该值
System.out.println("add 1 to maxValue of byte is "
+ (maxValue + ((byte) 2)));
输出结果为 129。
原因是这里发生的事情是 Integer addition
。不是字节赋值。所以你没有看到任何异常。
当您将字节转换值添加到 maxValue
时,它会立即变成整数加法。
要检查您的实际问题,请尝试做
byte maxValue2 =(maxValue + ((byte) 2));
这将无法编译,因为结果是一个 int。因此,当您将代码更改为
int maxValue2 = maxValue + ((byte) 2);
行得通。
当你在将结果转换为字节的帮助下进行字节赋值时,现在再次回到你的旧解释
byte maxValue2 = (byte) (maxValue + ((byte) 2));
现在您可以静静地看到溢出并截断整数的高阶位,并将 maxValue2 的结果截断为 -127
。
第一个问题是您先将 127 连接到字符串,然后再连接 2。因此您看到的值实际上是“1272”。
但是当您将 (maxValue + (byte)2)
放在括号中时,您会遇到另一个问题:+
运算符导致 二进制数字提升 。这在Java Language Specification, item 5.6.2:
中提到
When an operator applies binary numeric promotion to a pair of
operands, each of which must denote a value that is convertible to a
numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing
conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or
both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
后面是导致这种二进制数字提升的运算符列表,它包括运算符 +
。
所以你看,两个操作数都转换为int
。并变成 127 + 2
,不会溢出 int
范围。结果是 int
.
要查看实际溢出,您可能需要执行以下操作:
byte newValue = (byte) (maxValue + (byte)2); // Notice that you can't assign it without the cast!
System.out.println(newValue);
这个溢出实际上并不是加 2 的结果,而是截断整数 129
并只取其最右边的字节的结果。
class Overflowtest {
public static void main(String[] args) {
byte maxValue= Byte.MAX_VALUE;
System.out.println("maxValue of byte is "+maxValue);
System.out.println("add 1 to maxValue of byte is "+maxValue+(byte)2);
}
}
为什么我尝试maxValue+(byte)2
时没有发生溢出?
但如果我这样做,(byte)(maxValue+2)
,就会发生溢出。
在您的示例中,您将 127 添加到一个字符串,然后将 2 添加到一个字符串。
但是当你这样做时:
System.out.println(maxValue+(byte)2);
二元运算return一个整数。
正如其他人在解决括号后所说的那样,您可以打印该值
System.out.println("add 1 to maxValue of byte is "
+ (maxValue + ((byte) 2)));
输出结果为 129。
原因是这里发生的事情是 Integer addition
。不是字节赋值。所以你没有看到任何异常。
当您将字节转换值添加到 maxValue
时,它会立即变成整数加法。
要检查您的实际问题,请尝试做
byte maxValue2 =(maxValue + ((byte) 2));
这将无法编译,因为结果是一个 int。因此,当您将代码更改为
int maxValue2 = maxValue + ((byte) 2);
行得通。
当你在将结果转换为字节的帮助下进行字节赋值时,现在再次回到你的旧解释
byte maxValue2 = (byte) (maxValue + ((byte) 2));
现在您可以静静地看到溢出并截断整数的高阶位,并将 maxValue2 的结果截断为 -127
。
第一个问题是您先将 127 连接到字符串,然后再连接 2。因此您看到的值实际上是“1272”。
但是当您将 (maxValue + (byte)2)
放在括号中时,您会遇到另一个问题:+
运算符导致 二进制数字提升 。这在Java Language Specification, item 5.6.2:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
后面是导致这种二进制数字提升的运算符列表,它包括运算符 +
。
所以你看,两个操作数都转换为int
。并变成 127 + 2
,不会溢出 int
范围。结果是 int
.
要查看实际溢出,您可能需要执行以下操作:
byte newValue = (byte) (maxValue + (byte)2); // Notice that you can't assign it without the cast!
System.out.println(newValue);
这个溢出实际上并不是加 2 的结果,而是截断整数 129
并只取其最右边的字节的结果。