简体   繁体   English

为什么使用整型变量会抛出异常?

[英]Why does the use of integer variables throw an exception?

I have come across with the following two codes.我遇到了以下两个代码。 Why does it not throw an exception for floating point where as in other case it will throw a runtime exception.为什么它不抛出浮点异常,而在其他情况下它会抛出运行时异常。

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

OUTPUT:b=Infinity .输出:b=无穷大

If I try with int values then it will throw a runtime exception.如果我尝试使用 int 值,那么它会抛出运行时异常。 Why is it like this?为什么会这样?

The short answer简短的回答

Integral types ( JLS 4.2.1 ) are categorically different from floating point types ( JLS 4.2.3 ).整型类型 ( JLS 4.2.1 ) 与浮点类型 ( JLS 4.2.3 ) 截然不同。 There may be similarities in behavior and operations, but there are also characteristically distinguishing differences such that confusing the two can lead to many pitfalls.在行为和操作上可能有相似之处,但也存在特征上的区别,将两者混淆可能会导致许多陷阱。

The difference in behavior upon division by zero is just one of these differences.除以零时的行为差异只是这些差异之一。 Thus, the short answer is that Java behaves this way because the language says so.因此,简短的回答是 Java 的行为方式是因为语言是这样说的。


On integral and floating point values关于整数和浮点值

The values of the integral types are integers in the following ranges:整数类型的值是以下范围内的整数:

  • byte : from -128 to 127 , inclusive, ie [-2 7 , 2 7 -1] byte :从-128127 ,包括在内,即[-2 7 , 2 7 -1]
  • short : from -32768 to 32767 , inclusive, ie [-2 15 , 2 15 -1] short :从-3276832767 ,包括在内,即[-2 15 , 2 15 -1]
  • int : from -2147483648 to 2147483647 , inclusive, ie [-2 31 , 2 31 -1] int : 从-21474836482147483647 ,包括在内,即[-2 31 , 2 31 -1]
  • long : from -9223372036854775808 to 9223372036854775807 , inclusive, ie [-2 63 , 2 63 -1] long :从-92233720368547758089223372036854775807 ,包括在内,即[-2 63 , 2 63 -1]
  • char , from '\' to '\￿' inclusive, that is, from 0 to 65535 , ie [0, 2 16 -1] char ,从'\''\￿'包含,即从065535 ,即[0, 2 16 -1]

The floating-point types are float and double , which are conceptually associated with the single-precision 32-bit and double-precision 64-bit format IEEE 754 values and operations.浮点类型是floatdouble ,它们在概念上与单精度 32 位和双精度 64 位格式IEEE 754值和操作相关联。

Their values are ordered as follows, from smallest to greatest:它们的值按从最小到最大的顺序排列如下:

  • negative infinity,负无穷大,
  • negative finite nonzero values,负有限非零值,
  • positive and negative zero (ie 0.0 == -0.0 ),正负零(即0.0 == -0.0 ),
  • positive finite nonzero values, and正有限非零值,和
  • positive infinity.正无穷大。

Additionally, there are special Not-a-Number ( NaN ) values, which are unordered .此外,还有特殊的Not-a-Number ( NaN ) 值,它们是无序的 This means that if either (or both!) operand is NaN :这意味着如果其中一个(或两个!)操作数是NaN

  • numerical comparison operators < , <= , > , and >= return false数值比较运算符<<=>>=返回false
  • numerical equality operator == returns false数值相等运算符==返回false
  • numerical inequality operator != returns true数值不等式运​​算符!=返回true

In particular, x != x is true if and only if x is NaN .特别是, x != xtrue当且仅当xNaN

For eg double , the infinities and NaN can be referred to as:例如double ,无穷大和NaN可以被称为:

The situation is analogous with float and Float .这种情况类似于floatFloat


On when exceptions may be thrown关于何时可能抛出异常

Numerical operations may only throw an Exception in these cases:在这些情况下,数值运算可能只抛出Exception

  1. NullPointerException , if unboxing conversion of a null reference is required NullPointerException ,如果需要对null引用进行拆箱转换
  2. ArithmeticException , if the right hand side is zero for integer divide/remainder operations ArithmeticException ,如果整数除法/余数运算的右侧为零
  3. OutOfMemoryError , if boxing conversion is required and there is not sufficient memory OutOfMemoryError ,如果需要装箱转换且内存不足

They are ordered by importance, with regards to being common source for pitfalls.它们按重要性排序,因为它们是陷阱的常见来源。 Generally speaking:通常来说,一般来说:

  • Be especially careful with box types, as just like all other reference types, they may be null对框类型要特别小心,就像所有其他引用类型一样,它们可能为null
  • Be especially careful with the right hand side of an integer division/remainder operations对整数除法/余数运算的右侧要特别小心
  • Arithmetic overflow/underflow DOES NOT cause an exception to be thrown算术上溢/下溢不会导致抛出异常
  • Loss of precision DOES NOT cause an exception to be thrown精度损失不会导致抛出异常
  • A mathematically indefinite floating point operation DOES NOT cause an exception to be thrown数学上不确定的浮点运算不会导致抛出异常

On division by zero除以零

For integer operation:对于整数运算:

  • Division and remainder operations throws ArithmeticException if the right hand side is zero如果右侧为零,除法和余数运算会抛出ArithmeticException

For floating point operation:对于浮点运算:

  • If the left operand is NaN or 0 , the result is NaN .如果左操作数为NaN0 ,则结果为NaN
  • If the operation is division , it overflows and the result is a signed infinity如果运算是除法,则溢出,结果为有符号无穷大
  • If the operation is remainder , the result is NaN如果运算为余数,则结果为NaN

The general rule for all floating point operation is as follows:所有浮点运算的一般规则如下:

  • An operation that overflows produces a signed infinity.溢出的操作会产生有符号无穷大。
  • An operation that underflows produces a denormalized value or a signed zero.下溢操作会产生非规范化值或有符号零。
  • An operation that has no mathematically definite result produces NaN .没有数学上确定结果的运算会产生NaN
  • All numeric operations with NaN as an operand produce NaN as a result.所有以NaN作为操作数的数值运算都会产生NaN作为结果。

Appendix附录

There are still many issues not covered by this already long answer, but readers are encouraged to browse related questions and referenced materials.这个已经很长的答案还有很多问题没有涉及,但鼓励读者浏览相关问题和参考资料。

Related questions相关问题

Because floats actually have a representation for the "number" you're trying to calculate.由于彩车事实上对“数字”表示你想计算。 So it uses that.所以它使用那个。 An integer has no such representation.整数没有这样的表示。

Java (mostly) follows IEEE754 for its floating point support, see here for more details. Java(主要)遵循 IEEE754 以提供浮点支持,有关更多详细信息,请参见此处

It is because integer arithmetic always wraps it's result except for the case of (Division/Remainder By Zero).这是因为整数算术总是包装它的结果,除了(除数/余数为零)的情况。
In case of float, when there is an overflow or underflow, the wrapping goes to 0, infinity or NaN.在浮点数的情况下,当出现上溢或下溢时,包装会变为 0、无穷大或 NaN。
During the overflow, it gives infinity and during underflow, it gives 0.在上溢期间,它给出无穷大,而在下溢期间,它给出 0。
Again there are positive & negative overflow/underflow.再次有正和负上溢/下溢。
Try:尝试:

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

This gives a negative overflow这给出了一个负溢出

Output输出

b=-Infinity b=-无穷大

Similarly positive underflow will result in 0 and negative underflow in -0.同样,正下溢将导致 0,负下溢将导致 -0。
Certain operations can also result in returning a NaN(Not a Number) by float/double.某些操作也可能导致浮点/双精度返回 NaN(非数字)。
For eg:例如:

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

Output输出

b=NaN b=NaN

It's a programming and math standard for representing / by zero values.它是用零值表示 / 的编程和数学标准。 float has support for representing such values in JAVA. float 支持在 JAVA 中表示这些值。 int (integer) data type doesn't have way to represent same in JAVA. int(整数)数据类型在 JAVA 中无法表示相同。

Check :查看 :

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM