質問

非数学的な理由で未定義の値にIEEE754浮動小数点NaN(not-a-number)を使用するのは良い考えですか?

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

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

NaNを使用するのはクリーンなソリューションのように思えますが、価値があるよりも手間がかかり、他の値を選択する必要がありますか?

役に立ちましたか?

解決

この質問に気付いた。

これは、IEEE 754委員会が念頭に置いているNaNの使用法の1つです(私は委員会のメンバーでした)。算術におけるNaNの伝播規則は、これを非常に魅力的なものにします。これは、初期化されたデータを含む長い計算シーケンスの結果がある場合、結果を有効な結果と間違えないためです。また、計算をトレースバックして、初期化されたデータを使用している場所をより簡単に見つけることができます。

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

他のヒント

NaNは「値なし」のセンテンスには適切な選択です(たとえば、Dプログラミング言語では初期化されていない値に使用されます)が、それらに関連する比較はすべて偽であるため、いくつかの驚きがあります:

    Jonが述べたように、 DEFAULT_VALUE がNaNの場合、
  • if(result == DEFAULT_VALUE)は期待どおりに動作しません。

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

bool isOutsideRange(double x, double minValue, double maxValue)
{
    return x < minValue || x > maxValue;
}

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

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

[編集:最初は&quot;それらに関連する比較はすべてtrueになります&quot;上記、これは私が意図したものではなく、間違っていますが、NaN!= NaN(true)を除き、すべて偽です]

同じ理由でNaNを使用したのは、そのためだけです。通常のデフォルトの初期化値0も有効な値です。これまでのところ、NaNは正常に機能しています。

ちなみに、デフォルトの初期化値が通常(たとえば、Javaプリミティブ型の場合)0であり、NaNではない理由は、良い質問です。 42でも何でもないでしょうか?ゼロの原理は何だろうか。

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

適切な解決策は、「価値の欠如」のエンコードを避けることです。フロートで、しかし別の方法でそれを知らせるために。ただし、コードベースによっては、必ずしも実用的ではありません。

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

これらは、floatに対して完全に有効な値ですが、それらに関係する代入もNaNと等しいため、コードを介して伝播されます。これをデバッグツールとしてキャッチすると非常に優れていますが、リリースするものを持ち込んでいて、どこかにフリンジケースがある場合は、非常に迷惑になります。

Dは、これをデフォルトとしてフロートNaNを与える理由として使用します。 (同意するかどうかわかりません。)

それは少しハックですが、少なくともこのNaN値で操作を行うすべての数値は結果としてNaNを与えます-バグレポートでNaNを見ると、少なくともあなたはどんな種類の間違いかを知っています狩り。

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

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

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

もちろん、ウイルスのように増殖するはずです。それがポイントです。

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

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top