所以我知道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设计者的选择?如果这种演员表能够例外,是否会产生不良后果?
答案 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)
在JLS中,请参阅: JavaRanch post http://www.coderanch.com/t/239753/java-programmer-SCJP/certification/cast-double-int 但是警告会很好。
答案 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