13

非数学的な理由で定義されていない値に IEEE754 浮動小数点 NaN (非数) を使用することは良い考えですか?

この場合、他のデバイスから値が受信されていないため、値はまだ設定されていません。コンテキストは、IEC1131 REAL32 値を使用する組み込みシステムです。編集:プログラミング言語は C であるため、C99 の NAN と isnanf(x) を使用する可能性が最も高いでしょう。これらをOS互換レイヤーに入れるには、いくつかの追加のゆがみが必要になる場合があります.

プログラミング言語のデフォルトは、内部表現がすべてゼロの浮動小数点変数を正のゼロで初期化するようです。0 は有効な値の範囲内にあるため、これは使用できません。

NaN を使用するのはクリーンなソリューションのように思えますが、おそらくそれは価値があるよりも面倒なので、他の値を選択する必要がありますか?

4

9 に答える 9

11

この質問に今気づきました。

これは、IEEE 754 委員会が考えている NaN の使用法の 1 つです (私は委員会のメンバーでした)。算術演算における NaN の伝播規則により、これは非常に魅力的になります。初期化されたデータを含む長い一連の計算の結果が得られた場合、その結果を有効な結果と間違えないからです。また、計算をさかのぼって、初期化されたデータを使用している場所をより簡単に見つけることができます。

とはいえ、754 委員会の管理外にあるいくつかの落とし穴があります。他の人が指摘しているように、すべてのハードウェアが高速で NaN 値をサポートしているわけではないため、パフォーマンスが低下する可能性があります。幸いなことに、パフォーマンスが重要な設定で、初期化されたデータに対して多くの操作を行うことはあまりありません。

于 2009-10-15T16:25:39.303 に答える
4

NaN は「値のない」センテンシャル (たとえば、D プログラミング言語では初期化されていない値に使用されます) には妥当な選択ですが、NaN を含む比較はすべて false になるため、いくつか驚くべきことがあります。

  • if (result == DEFAULT_VALUE)DEFAULT_VALUE、ジョンが述べたように、が NaN の場合、期待どおりに機能しません。

  • 注意しないと、範囲チェックで問題が発生する可能性もあります。関数を考えてみましょう:

bool isOutsideRange(double x, double minValue, double maxValue)
{
    x < 最小値を返します || x > maxValue;
}

x が NaN の場合、この関数は、x が minValue と maxValue の間にあると誤って報告します。

ユーザーがテストする魔法の値だけが必要な場合は、同じトラップが付属していないため、NaN の代わりに正または負の無限大をお勧めします。NaN に対するすべての操作が NaN になるというプロパティが必要な場合は、NaN を使用します。たとえば、呼び出し元が値をチェックすることに依存したくない場合に便利です。

[編集: 最初に、上記の「それらを含むすべての比較が真になる」と入力することができましたが、これは私が意図したものではなく、間違っています。真である NaN != NaN を除いて、それらはすべて偽です]

于 2009-06-24T07:41:37.343 に答える
3

一般的には悪い考えだと思います。覚えておくべきことの1つは、ほとんどのCPUがNanを「通常の」フロートよりもはるかに遅く処理することです。そして、あなたが通常の設定でナンを決して持たないことを保証するのは難しいです。数値計算での私の経験は、それが価値があるよりも多くの問題をもたらすことが多いということです。

正しい解決策は、フロートで「値の欠如」をエンコードすることを避け、別の方法でそれを通知することです。ただし、コードベースによっては、これが常に実用的であるとは限りません。

于 2009-06-24T18:31:29.067 に答える
3

私が同様の状況で NaN を使用したのは、そのためです。通常のデフォルトの初期値 0 も有効な値です。NaN は今のところ問題なく動作します。

ところで、デフォルトの初期化値が通常 (たとえば Java プリミティブ型で) NaN ではなく 0 である理由は良い質問です。42とかでもいいんじゃない?ゼロの論理的根拠は何だろうと思います。

于 2009-06-24T06:30:00.117 に答える
2

NaN には注意してください... 注意しないと、野火のように広がる可能性があります。

これらは float に対して完全に有効な値ですが、それらを含む代入も NaN と等しくなるため、コードを通じて伝播されます。これは、デバッグ ツールとしては非常に優れていますが、リリースするものを持ってきて、どこかにフリンジ ケースがある場合は、非常に厄介です。

D はこれを、float NaN をデフォルトとして与える根拠として使用します。(私が同意するかどうかはわかりません。)

于 2009-06-24T08:42:06.283 に答える
1

ちょっとハッキリしているような気がしますが、少なくともこの NaN 値を使用して演算を行う他のすべての数値は結果として NaN を返します。バグ レポートで NaN を見れば、少なくともどのような間違いを探しているかがわかります。

于 2009-06-24T08:16:36.133 に答える
0

これは私にはnansの良い使い方のように聞こえます。考えていたらよかった…

確かに、彼らはウイルスのように繁殖することになっています、それがポイントです。

無限大の代わりにnanを使うと思います。シグナリングnanを使用して、最初の使用時にイベントを発生させるのは良いことかもしれませんが、それまでには、最初の使用では静かになるはずです。

于 2009-07-10T21:26:54.973 に答える
0

あなたの基本的な必要性が、デバイスから受信した可能性のある数値を表さない浮動小数点値を持つことでありデバイスが決して NaN を返さないことを保証する場合、それは私には合理的です。

環境によっては、おそらく NaN を検出する特別な方法が必要になることを覚えておいてください (単に使用しif (x == float.NaN)たり、同等のものを使用したりしないでください)。

于 2009-06-24T06:30:27.307 に答える
0

デフォルト値として NaN を使用することは合理的です。

(0.0 / 0.0) などの一部の式は NaN を返すことに注意してください。

于 2009-07-10T21:34:13.337 に答える