我想知道为什么这段代码执行时没有投掷RuntimeException
(确切ArithmethicException):
代码:
public class Proba {
public static void main(String[] args) {
Double d = new Double(5.0);
try {
d = d / 0;
} catch (Exception e) {
System.out.println("Error division by zero!");
}
System.out.println("d = " + d);
}
}
输出:
d = Infinity
我想知道它是怎么回事。
我的java版本是:
C:\Documents and Settings\Admintemp>java -version
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)
答案 0 :(得分:13)
这是可能的,因为Java遵循IEEE标准进行浮点除法。
确实整数除以0将抛出ArithmeticException
,但浮点除以0会产生Infinity
的特殊浮点值。
详细说明,the JLS, Section 15.17.2说:
[I] f整数除法中除数的值为0,然后抛出ArithmeticException。
和
浮点除法的结果由规则确定 IEEE 754算术:
(剪断)
将零非零有限值除以零会导致签名 无穷。该标志由上述规则决定。
这提出了一个问题,“为什么IEEE声明它应该是
Infinity
而不是某种错误?“这是IEEE's
explanation:
为什么不将零除(或溢出或下溢)停止 程序或触发错误?为什么数字标准包括 “不是号码”(NaN)? 754模型鼓励强大的计划。它是 不仅适用于数值分析师,也适用于电子表格 用户,数据库系统,甚至咖啡壶。传播规则 因为NaN和无穷大允许无关紧要的例外消失。 类似地,逐渐下溢维持错误属性 精度范围。
当需要注意特殊情况时,可以检查它们 立即通过陷阱或在方便的时候通过状态标志。陷阱 可用于停止程序,但不可恢复的情况 非常罕见。简单地停止一个程序不是一个选择 嵌入式系统或网络代理。更常见的是,陷阱记录诊断 信息或替代有效结果。
Flags提供可预测的控制流程和速度。他们的用途 要求程序员注意异常条件,但要标记 粘性允许程序员延迟处理异常情况 直到必要。