为什么将Double.NaN转换为int不会在Java中抛出异常?

时间:2011-05-03 22:16:24

标签: java casting floating-point ieee-754

所以我知道IEEE 754为非实数的值指定了一些特殊的浮点值。在Java中,将这些值转换为基元int会使像我期望的那样抛出异常。相反,我们有以下内容:

int n;
n = (int)Double.NaN; // n == 0
n = (int)Double.POSITIVE_INFINITY; // n == Integer.MAX_VALUE
n = (int)Double.NEGATIVE_INFINITY; // n == Integer.MIN_VALUE

在这些情况下抛出异常的理由是什么?这是IEEE标准,还是仅仅是Java设计者的选择?如果这种演员表能够例外,是否会产生不良后果?

5 个答案:

答案 0 :(得分:10)

  

在这些情况下不抛出异常的理由是什么?

我想,原因包括:

  • 这些是边缘情况,很可能在执行此类操作的应用程序中很少发生。

  • 行为并非“完全出乎意料”。

  • 当应用程序从double转换为int时,预计会出现重大信息丢失。该应用程序要么忽略这种可能性,要么演员之前将进行检查以防止它...这也可以检查这些情况。

  • 没有其他双重/浮动操作导致异常,而(IMO)在这种情况下执行此操作会有点精神分裂。

  • 某些硬件平台(当前或未来)可能会出现性能损失。

  

这是IEEE标准,还是仅仅是Java设计者的选择?

后者,我想。

  

是否会产生不良后果,我不知道是否可以使用此类演员进行例外处理?

除了显而易见的......

(但它并不是真正相关.JLS和JVM规范说出了他们所说的内容,而更改它们将会破坏现有代码。而且我们现在讨论的不只是Java代码......)


我做了一些挖掘工作。许多可以使用的x86指令从double转换为整数似乎生成硬件中断......除非屏蔽。 (对我而言)不清楚指定的Java行为是否比OP建议的替代方案更容易或更难实现。

答案 1 :(得分:8)

答案 2 :(得分:3)

1998年有一个ACM演示文稿仍然看起来令人惊讶,并带来一些亮点:https://people.eecs.berkeley.edu/~wkahan/JAVAhurt.pdf

更具体地说,关于铸造NaN和无穷大时出人意料的缺乏例外情况:见第3页,第3点:“没有保护浮点陷阱和IEEE标准754/854规定的标志释放的无穷大和NaN相信Java的主张坚强。“

该演示文稿并未真正回答“为什么”,但确实解释了Java语言浮点实现中有问题的设计决策的后果,并将它们置于IEEE标准甚至其他实现的上下文中。 / p>

答案 3 :(得分:1)

答案 4 :(得分:1)

实际上我认为在某些演员阵容中有位操作(可能是针对性能问题?),这样你就可以有一些意想不到的行为。看看使用>>时会发生什么和<<运算符。

例如:

public static void main(String[] args) {
    short test1 = (short)Integer.MAX_VALUE;
    System.out.println(test1);
    short test2 = (short)Integer.MAX_VALUE-1;
    System.out.println(test2);
    short test3 = (short)Integer.MAX_VALUE-2;
    System.out.println(test3);
    short test4 = (short)Double.MAX_VALUE-3;
    System.out.println(test4);
}

将输出:

-1
-2
-3
-4
相关问题