为什么将整数除以零并将其强制转换为浮点数会产生无穷大?

时间:2011-09-08 01:44:58

标签: java floating-point divide-by-zero

我已经在这个主题上搜索了不同的问题,但没有明确的想法。 检查此代码:

class Test{
    public static void main(String[] s){
        int a=5;
        float b=(float)a/0;
        System.out.print(b);
    }
}

输出为Infinity。但我没有得到的是ainta/0必须抛出异常。那么它如何显示输出Infinity

8 个答案:

答案 0 :(得分:8)

原因是

(float)a/0;

被解释为

((float)a)/0;

而不是

(float)(a/0);

所以你实际上在进行除法之前将a转换为float,而不是进行整数除法然后转换结果。

希望这有帮助!

答案 1 :(得分:4)

您没有将整数除以零。您将float除以零,因为您的表达式等同于:

float b=((float)a)/0;

如果强制除法仅使用整数,如下例所示,the expected ArithmeticException will be thrown

float b=(float)(a/0);

答案 2 :(得分:2)

所有浮点计算均遵循IEEE 754规范。特别是那里 是三个特殊的浮点值来表示溢出和错误:

•正无穷大 •负无穷大 •NaN(不是数字)

例如,将正数除以0的结果是正无穷大。计算 0/0或负数的平方根产生NaN。

另见

  

注意:浮点数不适合财务   计算中不能容忍舍入误差。例如,   命令System.out.println(2.0 -   1.1)打印0.8999999999999999,而不是你想象的0.9。这样   舍入误差是由浮点数引起的   以二进制数系统表示。没有精确的二进制文件   分数1/10的表示,就像没有准确的一样   十进制系统中1/3分数的表示。如果你需要   没有舍入误差的精确数值计算,使用   BigDecimal类,将在本章后面介绍。

来自核心Java Volume 1第3章

答案 3 :(得分:1)

a是一个int,除了在分割发生时将它转换为浮点数。请注意,强制转换的优先级高于除法 - 为了清晰起见,括号为:

float b = ((float) a)/0;

因此,当a是一个int时,你正在进行浮点除法。

答案 4 :(得分:1)

这是因为Java不允许使用int进行除零,而使用浮点值进行

答案 5 :(得分:1)

如果浮点运算创建了一个无法正常表示的大浮点数,则会生成

Infinity

a的强制转换生成0自动转换为浮动

答案 6 :(得分:1)

因为您将a投射到浮点数,然后除以零。浮点数为+/-无穷大。

http://www.velocityreviews.com/forums/t137207-division-by-zero-float-vs-int.html

答案 7 :(得分:0)

二进制/运算符执行除法,产生其操作数的商。左手操作数是被除数,右手操作数是除数。

整数除法向0舍入。也就是说,操作数n和d为二进制数字提升后的整数(第5.6.2节)产生的商是一个整数值q,其大小尽可能大,同时满足| d· q || N |;此外,当| n || d |时,q为正并且n和d具有相同的符号,但当| n || d |时q为负和n和d有相反的符号。有一种特殊情况不满足此规则:如果被除数是其类型的最大可能量值的负整数,且除数为-1,则发生整数溢出,结果等于被除数。尽管溢出,但在这种情况下不会抛出异常。另一方面,如果整数除法中的除数值为0,则抛出ArithmeticException。

浮点除法的结果由IEEE算法规范确定:

If either operand is NaN, the result is NaN.
If the result is not NaN, the sign of the result is positive if both operands have the same sign, negative if the operands have different signs.
Division of an infinity by an infinity results in NaN.
Division of an infinity by a finite value results in a signed infinity. The sign is determined by the rule stated above.
Division of a finite value by an infinity results in a signed zero. The sign is determined by the rule stated above.
Division of a zero by a zero results in NaN; division of zero by any other finite value results in a signed zero. The sign is determined by the rule stated above.
Division of a nonzero finite value by a zero results in a signed infinity. The sign is determined by the rule stated above.
In the remaining cases, where neither an infinity nor NaN is involved, the exact mathematical quotient is computed. A floating-point value set is then chosen:
    If the division expression is FP-strict (§15.4):
        If the type of the division expression is float, then the float value set must be chosen.
        If the type of the division expression is double, then the double value set must be chosen. 
    If the division expression is not FP-strict:
        If the type of the division expression is float, then either the float value set or the float-extended-exponent value set may be chosen, at the whim of the implementation.
        If the type of the division expression is double, then either the double value set or the double-extended-exponent value set may be chosen, at the whim of the implementation. 

Next, a value must be chosen from the chosen value set to represent the quotient. If the magnitude of the quotient is too large to represent, we say the operation overflows; the result is then an infinity of appropriate sign. Otherwise, the quotient is rounded to the nearest value in the chosen value set using IEEE 754 round-to-nearest mode. The Java programming language requires support of gradual underflow as defined by IEEE 754 (§4.2.4). 

尽管可能会出现溢出,下溢,除零或信息丢失的情况,但评估浮点除法运算符/从不会引发运行时异常。

可在以下位置验证:http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.17.2