为什么用浮点(或双精度)数除零不会在Java中抛出java.lang.ArithmeticException:/ by

Tin*_*iny 57 java exception dividebyzeroexception arithmeticexception

以下陈述java.lang.ArithmeticException: / by zero显而易见.

System.out.println(0/0);
Run Code Online (Sandbox Code Playgroud)

因为文字0被认为是int文字并且在整数算术中不允许除以零.

但是,以下情况不会抛出任何异常java.lang.ArithmeticException: / by zero.

int a = 0;
double b = 6.199;
System.out.println((b/a));
Run Code Online (Sandbox Code Playgroud)

它显示Infinity.

以下语句生成NaN(非数字),没有例外.

System.out.println(0D/0); //or 0.0/0, or 0.0/0.0 or 0/0.0 - floating point arithmetic.
Run Code Online (Sandbox Code Playgroud)

在这种情况下,两个操作数都被认为是双精度数.


同样,以下语句不会抛出任何异常.

double div1 = 0D/0; //or 0D/0D
double div2 = 0/0D; //or 0D/0D

System.out.printf("div1 = %s : div2 = %s%n", div1, div2);
System.out.printf("div1 == div2 : %b%n", div1 == div2);
System.out.printf("div1 == div1 : %b%n", div1 == div1);
System.out.printf("div2 == div2 : %b%n", div2 == div2);
System.out.printf("Double.NaN == Double.NaN : %b%n", Double.NaN == Double.NaN);
System.out.printf("Float.NaN == Float.NaN : %b%n", Float.NaN == Float.NaN);
Run Code Online (Sandbox Code Playgroud)

它们产生以下输出.

div1 = NaN : div2 = NaN
div1 == div2 : false
div1 == div1 : false
div2 == div2 : false
Double.NaN == Double.NaN : false
Float.NaN == Float.NaN : false
Run Code Online (Sandbox Code Playgroud)

它们都返回false.为什么这个操作(除以零)允许使用浮点数或双精度数?


顺便说一句,我可以理解浮点数(双精度数)的值代表正无穷大, 负无穷大,而不是数字(NaN)......

Bil*_*ard 57

简而言之,这就是它在IEEE-754标准中指定的方式,这是Java的浮点运算所基于的.

为什么不将零除(或溢出或下溢)停止程序或触发错误?为什么数字标准包括"非数字"(NaN)?

754模型鼓励强大的计划.它不仅适用于数字分析师,也适用于电子表格用户,数据库系统甚至咖啡壶.NaN和无穷大的传播规则允许无关紧要的例外消失.同样,逐渐下溢会在精度范围内保持误差属性.

当需要注意特殊情况时,可以通过陷阱或在方便的时候通过状态标志立即检查它们.陷阱可用于停止程序,但不可恢复的情况极为罕见.简单地停止程序不是嵌入式系统或网络代理的选项.更常见的是,陷阱记录诊断信息或替换有效结果.

标志提供可预测的控制流程和速度.它们的使用要求程序员了解异常情况,但标志粘性允许程序员在必要时延迟处理异常情况.


Aln*_*tak 16

就是这样,因为IEEE 754就是这样定义的.

按浮点0.0划分得到NaN或+/- Inf,取决于分子是否为0.

IEEE 754不包括整数0除以产生异常 - 没有其他方法可以指示错误,因为它int不能表示NaNInf.

生成异常类似于INT在x86微处理器上由零除以生成的(软件).


Muk*_*oel 11

超越无限

class DoubleDivision {

    public static void main(String[] args) {
        System.out.println(5.0/0.0);
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码和你提到的代码片段给出了infinity.

为什么Java使用Doubles来表示小数.二进制不能完全表示一个数字,它只能表示近似值,因此,Java也不能加倍.

想象一个令人难以置信的接近零的数字.如果您了解微积分,请设想零限制.变量将接近零到一些可以想象的微小距离,但从不完全相等.你可以想象,对吗?好吧,假设这个数字需要如此精确的Java代表,它放弃并调用它,0.0因为它没有一个好的替代品.这就是这里发生的事情.任何常数除以超近数为零基本上是无穷大.试试吧:5 / (10^-100).

另请参阅以下部分:数学错误处的特殊浮点值以获取更多信息:)

相关问题:为什么1/0给出错误但1.0/0/0给出inf

更新: 在集合INT中没有无穷大和NaN值,而浮点数具有无穷大和NaN值.(根据IEEE遵循的IEEE 754标准)

  • _Binary不能完全表示一个数字,它只能表示一个近似值,因此,Java也不能加倍.一个零在(任何?)浮点表示法中是完全可表示的. (5认同)

Rae*_*ald 5

如果除以零,则计算机无法将结果表示为数字.计算机需要发出结果不是数字的信号.

对于浮点值,它可以产生一个特殊的非数字标记值,因为有一些32位(for float)和64位(for double)位模式不表示数字,因此可以解释为-a-number(NaN).

对于使用通用二进制补码方案的整数值(如Java所要求的),所有32位(for int)和64位(for long)位模式都代表一个数字.因此,计算机无法使用哨兵报告问题.它必须以某种方式"带外"报告问题.抛出异常是为Java选择的带外方法.