c - 除算 - 浮動小数点 加算方法




NaNをテストするための移植可能な方法は `x!= x`ですか? (2)

C規格の規範的な附属書F:IEC 60559浮動小数点演算を参照してください。

F.1はじめに

__STDC_IEC_559__を定義する実装は、この附属書の仕様に準拠しなければならない。

__STDC_IEC_559__を定義していない実装は、これらの仕様に準拠する必要はありません。

F.9.3関係演算子

xNaN場合、式x ≠ xNaNます。

XNan場合、式x = xはfalseです。

F.3演算子と関数

<math.h>isnanマクロは、IEC 60559の付録で推奨されているisnan関数を提供します。

Cでは、NaNがisnan(x)を使用している場合は、doubleかどうかをテストできます。 しかし、このSOの答えなど、オンラインの多くの場所では、代わりにx!=x使用することができます。

xがNaNであるかどうかをテストする方法として保証されている方法として、任意のC仕様でx!=xですか? 私は自分でそれを見つけることができません、そして私は私のコードが異なるコンパイラで動作することを望みます。


プロパティx!=x持つ唯一の値xとしてのNaNは、IEEE 754の保証です。 CでNaNを認識することが忠実なテストであるかどうかは、使用する予定のコンパイラで、変数と演算の表現がIEEE 754形式と演算にどの程度マッピングされているかによって決まります。

あなたは特に "超過精度"とコンパイラがそれをどう扱うかについて心配するべきです。 FPUがコンパイラがfloat型やdouble型に使用したいよりも広いフォーマットの計算のみを便利にサポートしている場合に、精度が超過します。 この場合、計算はより広い精度で行われ、コンパイラが予期しない方法で感じたときにその型の精度に丸められます。

C99標準では、NaNだけがそれ自体とは異なるという性質を維持するために、この超過精度を処理する方法を定義しました。ただし、1999年以降(およびコンパイラーの作者が気にしない今日でさえ)。 x != xは、コンパイラが最初のxと2番目のx評価の間に計算の超過精度の結果を丸めることを選択した場合、計算の有限結果を含むすべての変数x当てはまる可能性があります。

このreportは、C99を実装するための努力をしなかったコンパイラの暗黒時期について説明します(まだ1999年ではなかったため、または十分に気にかけていなかったため)。

この2008年の記事では、GCCが2008年に超精度のC99標準をどのように実装し始めたかについて説明しています。それ以前は、GCCは前述のレ​​ポートに記載されているすべての驚きを提供しました。

もちろん、ターゲットプラットフォームがIEEE 754をまったく実装していない場合は、NaN値が存在しないか、存在してIEEE 754で指定されているものとは異なるプロパティを持つ可能性があります。一般的なケースはFLT_EVAL_METHODセットでIEEE 754を非常に忠実に実装するコンパイラです。 0、1、または2( xがNaNの場合、 x != xであることがすべて保証されていx != x )、または標準外の超過精度の実装を持つコンパイラ( x != xはNaNの信頼性の高いテストではありません)。





nan