1. ホーム
  2. floating-point

[解決済み] なぜNaNはNaNと等しくないのですか?[重複あり]

2022-04-28 06:10:36

質問

IEEE規格では、数値定数NaN(not a number)を定義し、NaNはそれ自身と等しくないものとして比較するように規定しています。なぜでしょうか?

私が知っているすべての言語がこのルールを実装している。しかし、コンテナにNaNが格納されている場合、ソートされるデータの中にNaNがある場合など、予期せぬ動作をすることが多く、重大な問題を引き起こすことがあります。言うまでもなく、大多数のプログラマーは、(NaNについて学ぶ前は)どんなオブジェクトもそれ自身に等しいと期待しているので、彼らを驚かせることはバグと混乱を増やすことになります。

IEEE規格はよく考えられているので、NaNを自分自身と等しいと比較することが悪いというのは、それなりの理由があるのでしょう。ただ、それが何なのかがわからないのです。

編集:以下をご参照ください。 IEEE754のNaN値に対して、すべての比較がfalseを返す根拠は何ですか? を正式な回答としています。

どのように解決するのですか?

4年前の私の回答は、その決定がなされた背景を理解せず、現代の視点からその決定を批判したものです。そのため、質問の答えになっていません。

正解は以下の通りです。 こちら :

NaN != NaN は、2つの実用的な配慮から生まれました。

[はなかった。 isnan( ) 述語は、8087の算術でNaNが定式化された時点で、プログラマにNaN値を検出する便利で効率的な手段を提供する必要があり、プログラミング言語が次のようなものを提供することに依存しないようにしました。 isnan( ) それは何年もかかるかもしれない

この方法には1つデメリットがあって、数値計算とは関係ない多くの場面でNaNの使い勝手が悪くなってしまうのです。例えば、ずっと後になって、人々が NaN を利用して欠損値を表現し、ハッシュベースのコンテナに入れることができなかったのです。

もし委員会が将来のユースケースを予見し、それを十分に重要だと考えていたのなら、より冗長な !(x<x & x>x) の代わりに x!=x のテストとして NaN . しかし、彼らの関心はもっと実用的で狭く、数値計算のための最適解を提供することであり、そのようなアプローチに問題はないと考えていた。

===

オリジナルの回答です。

申し訳ありませんが、上位に投票された回答に込められた思いはありがたいのですが、私は反対です。NaNは、"undefined"という意味ではありません。 http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF 7ページ("undefined"で検索してください)。この文書で確認できるように、NaNは明確に定義された概念です。

さらに、IEEEのアプローチは、通常の数学のルールにできるだけ従い、それができないときは、"last surprise"のルールに従うというものでした - 参照。 https://stackoverflow.com/a/1573715/336527 . どんな数学的対象もそれ自身と等しいので、数学のルールでは、NaN==NaNは真であるべきということになります。このような数学の大原則から逸脱する有効かつ強力な理由は見当たりません(比較の三項対立などの重要度の低いルールは言うに及ばず)。

その結果、私の結論は次のようになります。

IEEEの委員はこのことをよく考えずに、間違いを犯してしまったのです。IEEE委員会のやり方を理解している人はほとんどいませんし、NaNについて規格が正確に何を言っているのかを気にしている人もいませんから(つまり、ほとんどのコンパイラのNaNの扱いは、いずれにしてもIEEE規格に違反しています)、誰も警鐘を鳴らしませんでした。そのため、この間違いが規格に組み込まれてしまったのです。そのような修正は多くの既存のコードを壊すことになるので、修正される可能性は低い。

編集する 以下は1つの記事です。 非常に有益な議論から。注:公平な見解を得るには、スレッド全体を読む必要があります。Guidoは他のコア開発者たちとは異なる見解を示しているからです。しかし、Guido は個人的にはこのトピックに興味がなく、Tim Peters の推奨にほぼ従っています。もし誰かが Tim Peters の NaN != NaN 私の意見を変える良い機会です。