为什么Java中的整数类型不能表示NaN?

10
当我写类似下面的内容时:
double a = 0.0;
double b = 0.0;
double c = a/b;

结果是Double.NaN,但当我对整数进行相同的操作时,它会产生一个ArithmeticException。那么,为什么没有Integer.NaN呢?


5
由于浮点数规范指定了NaN值,并且符合规范的实现必须正确处理它,而整数实现则没有这样的规范,并且没有办法明确地表示“无效值”。相关链接相关链接2 - Benjamin Gruenbaum
1
从你的问题历史记录来看,我已经将你的问题标记为Java编程语言。如果你提到的是其他语言,请标记为对应的语言。 - Lion
3个回答

9

这个答案与Java无关。 无穷大或未定义的数字不是整数集的一部分,因此它们被排除在Integer之外。而浮点类型表示实数和复数,因此为了处理这些情况,NaN已经包含在浮点类型中。


小知识:int i = (int)Float.NaN; // 0 - TWiStErRob

6
出于与其他语言相同的原因,计算机整数类型中也没有整数NaN
现代计算机使用2进制的2的补码表示法来表示整数,此表示法不包含NaN值。(表示类型的定义域中的所有值都代表明确的整数。)
由此可知,计算机整数运算硬件不会识别任何NaN表示法。
理论上,有人可以发明一种包括NaN(或INF或其他奇异值)的整数表示法。然而,使用这种表示法进行算术运算将不受硬件支持。虽然可以在软件中实现它,但成本会非常高昂,并且在其他方面也不希望在Java语言中包含这种支持。
相比之下:
- 表示空间中的"未使用"的值已经存在 - NaN和INF值是IEE浮点标准的一部分,以及 - 它们通常由浮点运算的本地硬件实现

1
我不同意“代价过高”的说法 - 这是一个相对的术语,它可能比绕过问题的成本更便宜。至于是否不可取 - 不知道,也许吧。我认为,如果这个概念适用于双精度浮点数,那么它对整数也可能有用。只是因为整数的底层实现没有提供它,所以它没有被实现,这实际上意味着,由于双精度浮点数的内部表示和范围允许它,因此需要存在不同的实现来支持这个好主意。 - Bohemian
1
@Bohemian - 我们正在讨论将NaN整数纳入“语言”中是否过于昂贵。显然,如果应用程序确实需要NaN,则对他们来说并不是过于昂贵的。但大多数应用程序并不需要。 - Stephen C
但是,捏紧内存不是导致2000年大规模错误的原因吗?你肯定只会说“如果我们需要它,我们就需要它”。无论如何,我认为现在这样很好——实现已经浮现到语言中,但我对此感到满意。如果(例如)一个int需要5个字节的内存而不是4个字节,全球成本将是多少,我会非常感兴趣。这可能会成为博士论文的研究课题。 - Bohemian
1
这个答案过分强调了它的论点。使用二进制补码表示整数并不排除保留其中一个值用作NaN的情况。将极端负值用于此用途将恢复整数类型的良好对称性(它们在取反下会闭合)。非NaN整数格式的流行更多地是由于其便捷的模数/包装等理想特性,而不是实现成本(这些成本可以转移到硬件中,而不是软件,尽管这个答案可能有所偏见)。 - Eric Postpischil
@EJP:我认为这不仅仅是磁盘空间的问题。纸张上的视觉空间以及在较小程度上终端屏幕上的视觉空间可能同样重要。此外,使用两位数年份而非四位数也可以节省按键次数。 - supercat
显示剩余16条评论

1

正如其他评论中所指出的那样,这主要是因为NaN是浮点数的标准值。您可以在维基百科上阅读有关返回NaN的原因的文章:

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

请注意,整数只有一个原因会出现除以零的情况。浮点数有正无穷和负无穷两个值,而整数没有,并且与浮点规范中的NaN密切相关。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接