7

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

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

输出:b=无穷大

如果我尝试使用 int 值,那么它将引发运行时异常。为什么会这样?

4

4 回答 4

13

简短的回答

整数类型(JLS 4.2.1)与浮点类型(JLS 4.2.3)完全不同。行为和操作可能有相似之处,但也存在明显的区别,因此混淆两者可能会导致许多陷阱。

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


关于整数和浮点值

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

  • byte: 从-128127, 包括在内, 即[-27, 27-1]
  • short: 从-3276832767, 包括在内, 即[-215, 215-1]
  • int: 从-21474836482147483647, 包括在内, 即[-231, 231-1]
  • long: 从-92233720368547758089223372036854775807, 包括在内, 即[-263, 263-1]
  • char, from '\u0000'to '\uffff'inclusive, 即从0to 65535, 即[0, 216-1]

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

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

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

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

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

特别x != xtrue当且仅当is 时xis NaN

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

情况与float和类似Float


何时可能引发异常

数值运算只能Exception在以下情况下抛出:

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

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

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

除以零

对于整数运算:

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

对于浮点运算:

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

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

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

附录

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

相关问题

于 2010-08-01T09:52:20.157 回答
12

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

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

于 2010-08-01T04:35:39.903 回答
2

这是因为整数运算总是包装它的结果,除了(除法/余数被零)的情况。
在浮点数的情况下,当发生上溢或下溢时,换行变为 0、无穷大或 NaN。
在上溢期间,它给出无穷大,在下溢期间,它给出 0。
同样有正负上溢/下溢。
尝试:

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

这给出了一个负溢出

输出

b=-无穷大

同样,正下溢将导致 0,负下溢将导致 -0。
某些操作还可能导致通过浮点/双精度返回 NaN(非数字)。
例如:

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

输出

b=NaN

于 2010-08-01T08:09:04.693 回答
1

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

查看 :

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

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

于 2010-08-01T08:46:14.070 回答