为什么NaN不等于NaN? [英] Why is NaN not equal to NaN?

查看:380
本文介绍了为什么NaN不等于NaN?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关的IEEE标准定义了数字常数NaN(不是数字),并规定NaN应该比较不等于其自身.为什么会这样?

The relevant IEEE standard defines a numeric constant NaN (not a number) and prescribes that NaN should compare as not equal to itself. Why is that?

我熟悉的所有语言都实现了此规则.但这通常会导致严重的问题,例如将NaN存储在容器中,将NaN放入正在排序的数据中时发生意外行为等.更不用说,绝大多数程序员都期望任何对象都等于自己(在他们了解NaN之前),令人惊讶的是,它们增加了错误和混乱.

All the languages I'm familiar with implement this rule. But it often causes significant problems, for example unexpected behavior when NaN is stored in a container, when NaN is in the data that is being sorted, etc. Not to mention, the vast majority of programmers expect any object to be equal to itself (before they learn about NaN), so surprising them adds to the bugs and confusion.

IEEE标准经过深思熟虑,因此我确信有充分的理由说明NaN等于其自身进行比较会很不好.我就是弄不清楚它是什么.

IEEE standards are well thought out, so I am sure there is a good reason why NaN comparing as equal to itself would be bad. I just can't figure out what it is.

请参考

please refer to What is the rationale for all comparisons returning false for IEEE754 NaN values? as the authoritative answer.

推荐答案

我的原始答案(来自4年前)从现代的角度批评了这一决定,而没有理解作出决定的背景.因此,它无法回答问题.

My original answer (from 4 years ago) criticizes the decision from the modern-day perspective without understanding the context in which the decision was made. As such, it doesn't answer the question.

正确的答案在此处:

NaN!= NaN源自两个务实的考虑因素:

NaN != NaN originated out of two pragmatic considerations:

[...]在8087算术中将NaN形式化时还没有isnan( )谓词;有必要为程序员提供一种便捷有效的方法来检测不依赖于编程语言的NaN值,例如isnan( )这样的代码可能要花费很多年

[...] There was no isnan( ) predicate at the time that NaN was formalized in the 8087 arithmetic; it was necessary to provide programmers with a convenient and efficient means of detecting NaN values that didn’t depend on programming languages providing something like isnan( ) which could take many years

该方法有一个缺点:在许多与数值计算无关的情况下,NaN的用处不大.例如,很久以后,当人们想要使用NaN表示缺失值并将其放入基于散列的容器中时,他们将无法做到这一点.

There was one disadvantage to that approach: it made NaN less useful in many situations unrelated to numerical computation. For example, much later when people wanted to use NaN to represent missing values and put them in hash-based containers, they couldn't do it.

如果委员会预见了未来的用例,并认为它们足够重要,则它们可能会选择更详细的!(x<x & x>x)而不是x!=x作为对NaN的检验.但是,他们的工作重点更加务实和狭窄:为数值计算提供最佳解决方案,因此他们认为他们的方法没有问题.

If the committee foresaw future use cases, and considered them important enough, they could have gone for the more verbose !(x<x & x>x) instead of x!=x as a test for NaN. However, their focus was more pragmatic and narrow: providing the best solution for a numeric computation, and as such they saw no issue with their approach.

===

原始答案:

很抱歉,尽管我很欣赏投票中最高答案的想法,但我不同意这一点. NaN并不意味着未定义"-请参见 http://www.cs.berkeley .edu/〜wkahan/ieee754status/IEEE754.PDF ,第7页(搜索单词"undefined").正如该文件所确认的那样,NaN是一个定义明确的概念.

I am sorry, much as I appreciate the thought that went into the top-voted answer, I disagree with it. NaN does not mean "undefined" - see http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF, page 7 (search for the word "undefined"). As that document confirms, NaN is a well-defined concept.

此外,IEEE方法是尽可能遵循常规的数学规则,而当它们不能遵循常规的数学规则时,则遵循最不惊奇"的规则-请参阅https://stackoverflow.com/a/1573715/336527 .任何数学对象都等于其自身,因此数学规则将暗示NaN == NaN应该为True.我看不出有任何有效而有力的理由背离这种主要的数学原理(更不用说比较三分法等次要的规则了.).

Furthermore, IEEE approach was to follow the regular mathematics rules as much as possible, and when they couldn't, follow the rule of "least surprise" - see https://stackoverflow.com/a/1573715/336527. Any mathematical object is equal to itself, so the rules of mathematics would imply that NaN == NaN should be True. I cannot see any valid and powerful reason to deviate from such a major mathematical principle (not to mention the less important rules of trichotomy of comparison, etc.).

结果,我的结论如下.

IEEE委员会成员对此不太清楚,并犯了一个错误.由于很少有人了解IEEE委员会的方法,或者很少关心标准关于NaN的确切含义(即:大多数编译器对NaN的处理仍然违反了IEEE标准),因此没有人发出警报.因此,此错误现在已嵌入标准中.它不太可能得到修复,因为这样的修复会破坏很多现有代码.

IEEE committee members did not think this through very clearly, and made a mistake. Since very few people understood the IEEE committee approach, or cared about what exactly the standard says about NaN (to wit: most compilers' treatment of NaN violates the IEEE standard anyway), nobody raised an alarm. Hence, this mistake is now embedded in the standard. It is unlikely to be fixed, since such a fix would break a lot of existing code.

这是一则帖子非常有益的讨论.注意:要获得无偏见,您必须阅读整个线程,因为Guido与其他一些核心开发人员的观点有所不同.但是,Guido个人对此主题不感兴趣,并且在很大程度上遵循了Tim Peters的建议.如果有人赞成蒂姆·彼得斯(Tim Peters)的论点支持NaN != NaN,请在评论中添加它们.他们有很大的机会改变我的看法.

Here is one post from a very informative discussion. Note: to get an unbiased view you have to read the entire thread, as Guido takes a different view to that of some other core developers. However, Guido is not personally interested in this topic, and largely follows Tim Peters recommendation. If anyone has Tim Peters' arguments in favor of NaN != NaN, please add them in comments; they have a good chance to change my opinion.

这篇关于为什么NaN不等于NaN?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆