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

下面的语句抛出java.lang.ArithmeticException: / by zero作为明显java.lang.ArithmeticException: / by zero

 System.out.println(0/0); 

因为文字0被认为是一个int文字,在整数运算中不允许被零除。

但是,下面的情况不会抛出像java.lang.ArithmeticException: / by zeroexceptionjava.lang.ArithmeticException: / by zero

 int a = 0; double b = 6.199; System.out.println((b/a)); 

它显示Infinity

下面的语句生成NaN (不是一个数字),没有例外。

 System.out.println(0D/0); //or 0.0/0, or 0.0/0.0 or 0/0.0 - floating point arithmetic. 

在这种情况下,两个操作数都被认为是双重的。


同样,下面的语句不会抛出任何exception。

 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); 

他们产生以下输出。

 div1 = NaN : div2 = NaN div1 == div2 : false div1 == div1 : false div2 == div2 : false Double.NaN == Double.NaN : false Float.NaN == Float.NaN : false 

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


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

简而言之,这就是IEEE-754标准所规定的方式,这就是Java的浮点运算所基于的。

为什么不用零除(或溢出或下溢)来停止程序或触发错误? 为什么数字标准包括“不是一个数字”(NaN)?

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

当特殊情况需要注意时,可以通过陷阱或通过状态标志在方便的时候立即检查。 陷阱可以用来停止一个程序,但不可恢复的情况是非常罕见的。 对于embedded式系统或networking代理而言,简单地停止程序不是一种select。 更常见的是,陷阱logging诊断信息或replace有效的结果。

标志提供可预测的控制stream程和速度。 它们的使用要求程序员注意特殊情况,但是标志粘性允许程序员在必要的情况下延迟处理exception情况。

就是这样,因为这就是IEEE 754对它的定义。

除以0.0的浮点数产生NaN或+/- Inf,取决于分子是否为0。

由整数0除法不被IEEE 754覆盖,并产生一个exception – 没有其他的方式来指示错误,因为int不能表示NaNInf

生成一个exception类似于x86微处理器上除以零产生的(软件) INT

超越无限

 class DoubleDivision { public static void main(String[] args) { System.out.println(5.0/0.0); } } 

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

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

想象一个令人难以置信的接近零的数字。 如果你知道微积分,设想一个极限为零。 variables将接近零到一个可以想象的微小距离,但永远不会完全相等。 你可以想象,对吧? 那么,假设这个数字对于Java来说需要非常精确的表示,那么它会放弃并把它称为0.0因为它没有一个好的select。 这就是这里发生的事情。 任何规则数除以超接近数为零基本上是无穷大 。 试试看: 5 / (10^-100)

有关更多信息,请参见math错误中的 特殊浮点值

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

更新: INT没有在集合中的无限和NaN值,而浮动具有无限和NaN值。 (根据java遵循的IEEE 754标准)

当除以零时,计算机不能以数字forms创build结果的表示forms。 计算机需要表示结果不是一个数字。

对于浮点值,它可以产生一个特殊的非数字定位值,因为有一些32位( float )和64位(对于double float )位模式不代表数字,因此可以解释作为非数字( NaN )。

对于使用普通二进制补码格式(如Java要求)的整数值,所有32位(对于int )和64位(对于long )位模式都表示一个数字。 所以计算机不能使用标记来报告问题。 它必须以某种方式“带外”报告问题。 抛出exception是为Javaselect的带外方法。

Java遵循IEEE 754标准,该标准定义在除零的情况下缺省返回的值。 http://en.wikipedia.org/wiki/IEEE_754#Exception_handling

除以零(对有限操作数的运算给出精确的无限结果,例如1/0或log(0))(默认返回±无穷大)。

 import java.util.Scanner; public class Division { public static void main(String[] args) { int a, b; float result; Scanner input = new Scanner(System.in); System.out.println("Enter value for a : "); a = input.nextInt(); System.out.println("Enter value for b : "); b = input.nextInt(); try { /* here we used "if clause" because result will be in float note: Here result is in float, so JVM Cant Catch Exception. if we Try to Divide with Zero with Float Values It gives Output as Divided by Zero is Infinity */ if (b != 0) { result = (float) a / b; System.out.println("Result of " + a + " divided by " + b + " is : " + result); } else // here result will be in integer so Jvm can easily Catch The Exception { result = a / b; } } catch (ArithmeticException e) { System.out.println("Sorry Division By Zero Is Not Possible"); } } } /* Ouput : Enter value for a :2 Enter value for b : 7 Result of 2 divided by 7 is : 0.2857143 */ /* Ouput : Enter value for a : 16 Enter value for b : 0 Sorry Division By Zero Is Not Possible */