为什么使用整数变量抛出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
:从-128
到127
,包括端点,即[-2
7
-1]
-
short
:从-32768
到32767
,包括在内,即[-2
15
, 2
15
-1]
-
int
:从-2147483648
到2147483647
,包括在内,即[-2
-2147483648
31
-1]
-
long
:从-9223372036854775808
到9223372036854775807
,包括在内,即[-2
-9223372036854775808
-1]
-
char
,从'\u0000'
到'\uffff'
包括0
到65535
,即[0, 2
16
-1]
浮点类型是float
和double
精度,它们在概念上与单精度32位和双精度64位格式IEEE 754值和运算相关联。
它们的值按如下顺序排列,从最小到最大:
- 负无穷大,
- 负有限非零值,
- 正负零(即
0.0 == -0.0
), - 正有限非零值,和
- 正无穷大。
此外,还有特殊的非数字 ( NaN
)值,这些值是无序的 。 这意味着如果其中一个(或两个!)操作数是NaN
:
- 数值比较运算符
<
,<=
,>
和>=
返回false
- 数字相等运算符
==
返回false
- 数值不等式运算符
!=
返回true
特别是,当且仅当x
是NaN
, x != x
为true
。
对于例如double
,无穷大和NaN
可以被称为:
-
Double.POSITIVE_INFINITY
-
Double.NEGATIVE_INFINITY
-
Double.NaN
,可用辅助方法测试boolean isNaN(double)
情况类似于float
和Float
。
在何时可能抛出exception
在这些情况下,数值运算只能抛出Exception
:
-
NullPointerException
,如果需要对null
引用进行拆箱转换 -
ArithmeticException
,如果右侧对整数除法/余数运算为零 -
OutOfMemoryError
,如果需要装箱转换且内存不足
关于陷阱的常见来源,它们按重要性排序。 一般来说:
- 对框类型要特别小心,就像所有其他引用类型一样,它们可能为
null
- 对整数除法/余数运算的右侧要特别小心
- 算术溢出/下溢不会导致抛出exception
- 精度损失不会导致exception抛出
- 数学上不确定的浮点运算不会导致抛出exception
按零除
对于整数运算:
- 如果右侧为零,则除法和余数运算会抛出
ArithmeticException
对于浮点运算:
- 如果左操作数是
NaN
或0
,则结果为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中表示相同。
检查: