为什么使用整数变量抛出exception?

我遇到了以下两个代码。 为什么它不会为浮点引发exception,而在其他情况下它会引发运行时exception。

class FloatingPoint { public static void main(String [] args) { float a=1000f; float b=a/0; System.out.println("b=" +b); } } 

输出:b =无穷大

如果我尝试使用int值,那么它将抛出运行时exception。 为什么会这样?

简短的回答

积分类型( JLS 4.2.1 )与浮点类型( JLS 4.2.3 )明显不同。 在行为和操作方面可能存在相似之处,但也存在区别性差异,使得混淆两者可能导致许多陷阱。

除以零时的行为差异只是这些差异之一。 因此,简短的回答是Java的行为方式是因为语言是这样说的。


关于积分和浮点值

整数类型的值是以下范围内的整数:

  • byte :从-128127 ,包括端点,即[-2 7 -1]
  • short :从-3276832767 ,包括在内,即[-2 15 , 2 15 -1]
  • int :从-21474836482147483647 ,包括在内,即[-2 -2147483648 31 -1]
  • long :从-92233720368547758089223372036854775807 ,包括在内,即[-2 -9223372036854775808 -1]
  • char ,从'\u0000''\uffff'包括065535 ,即[0, 2 16 -1]

浮点类型是floatdouble精度,它们在概念上与单精度32位和双精度64位格式IEEE 754值和运算相关联。

它们的值按如下顺序排列,从最小到最大:

  • 负无穷大,
  • 负有限非零值,
  • 正负零(即0.0 == -0.0 ),
  • 正有限非零值,和
  • 正无穷大。

此外,还有特殊的非数字NaN )值,这些值是无序的 。 这意味着如果其中一个(或两个!)操作数是NaN

  • 数值比较运算符<<=>>=返回false
  • 数字相等运算符==返回false
  • 数值不等式运​​算符!=返回true

特别是,当且仅当xNaNx != xtrue

对于例如double ,无穷大和NaN可以被称为:

  • Double.POSITIVE_INFINITY
  • Double.NEGATIVE_INFINITY
  • Double.NaN ,可用辅助方法测试boolean isNaN(double)

情况类似于floatFloat


在何时可能抛出exception

在这些情况下,数值运算只能抛出Exception

  1. NullPointerException ,如果需要对null引用进行拆箱转换
  2. ArithmeticException ,如果右侧对整数除法/余数运算为零
  3. OutOfMemoryError ,如果需要装箱转换且内存不足

关于陷阱的常见来源,它们按重要性排序。 一般来说:

  • 对框类型要特别小心,就像所有其他引用类型一样,它们可能为null
  • 对整数除法/余数运算的右侧要特别小心
  • 算术溢出/下溢不会导致抛出exception
  • 精度损失不会导致exception抛出
  • 数学上不确定的浮点运算不会导致抛出exception

按零除

对于整数运算:

  • 如果右侧为零,则除法和余数运算会抛出ArithmeticException

对于浮点运算:

  • 如果左操作数是NaN0 ,则结果为NaN
  • 如果操作是除法 ,它会溢出,结果是有符号无穷大
  • 如果操作是余数 ,则结果为NaN

所有浮点运算的一般规则如下:

  • 溢出的操作会产生有符号的无穷大。
  • 下溢的操作产生非规范化值或带符号的零。
  • 没有数学上明确结果的操作会产生NaN
  • NaN作为操作数的所有数值运算都会产生NaN

附录

这个已久的答案还没有涵盖很多问题,但鼓励读者浏览相关问题和参考资料。

相关问题

  • 这三个特殊的浮点值意味着什么:正无穷大,负无穷大,NaN?
  • 在Java中,NaN意味着什么。
  • 什么时候Java可以产生NaN(具有特定的代码问题)
  • 为什么(360/24)/ 60 = 0 ...在Java中 (区分整数与浮点运算!)
  • 为什么null == 0在Java中抛出NullPointerException? (注意盒装基元的危险!)
  • 1/0是合法的Java表达式吗? (绝对!!!)

因为浮点数实际上具有您尝试计算的“数字”的表示。 所以它使用它。 整数没有这样的表示。

Java(主要)遵循IEEE754的浮点支持,请参阅此处了解更多详细信息。

这是因为除了(Division / Remainder By Zero)的情况之外,整数运算总是包装它的结果。
在浮动的情况下,当存在溢出或下溢时,包裹变为0,无穷大或NaN。
在溢出期间,它给出无穷大,在下溢期间,它给出0。
同样存在正负溢出/下溢。
尝试:

 float a = -1000; float b = a/0; System.out.println("b=" +b); 

这给出了负溢出

产量

B = -Infinity

类似地,正下溢将导致0和负下溢-0。
某些操作也可能导致通过float / double返回NaN(非数字)。
例如:

 float a = -1000; double b = Math.sqrt(a); System.out.println("b=" +b); 

产量

B = NaN的

它是用于表示/通过零值的编程和数学标准。 float支持在JAVA中表示这些值。 int(整数)数据类型无法在JAVA中表示相同。

检查:

http://en.wikipedia.org/wiki/Division_by_zero

http://www.math.utah.edu/~pa/math/0by0.html