私は、以下の、比較的簡単(非常に効率的ではないが)、fabs
関数の実装があります。それは、このファブの実装はNaNに対して有効ですか?
double fabs(double x) {
if (x == 0.0) return 0.0; // deals with both 0.0 and -0.0.
if (x > 0.0) return x; // deals with ]0.0 .. +inf], but "(NaN > 0.0)" is false
return -x; // deals with [-inf .. 0.0[, and NaNs
}
のみ「落とし穴」私はこの実装で見つかったが、正のNaN与えられた、という事実であります負の値を返します。しかし、標準ではこれが許可されていないとは言えませんでした。特に
、ここで私が見つけたものです:
§7.12.7:
説明
ファブ関数は、浮動小数点数xの絶対値を計算します。
戻り値
fabs関数は、| x |を返します。
これは、数値ではないNaNの制約を課すものではありません。
F.10.4.2:
ファブ機能
- ファブ(±0)は0を返します。
- fabs(±∞)は+∞を返します。
戻り値は正確で、現在の丸め方向モードとは無関係です。
再び、NaNに制約はありません。
F.10、項目11:
関数のNaN引数ではNaNに結果を返し、特に明記しない場合を除き、いかなる浮動小数点例外を発生させません。
署名の制約はありません。
特に、signbit(fabs(x))
は浮動小数点x
に対して0を返すはずです。これは本質的に私の実装が侵害しているものです。
しかし、Ignorantia juris non excusatしたがって、この実装が適合していることを確認したいと思います。私が見つけたlibcの実装(glibc、musl)は、あらゆる種類の低レベルビットトリックやコンパイラ組み込み関数を効率的に使用するのに役立つわけではないので、この場合は多くの情報を提供しません。
私はコンパイラ自体が行うことよりも標準自体が必要とするものにもっと関心があるので、私はlanguage-lawyer
タグを付け加えました。たとえ "予期せぬ"マナーで作業していたとしても(MSVCはこれは、標準がそれほど厳しくないことを確認することができます(ただし、MSVCは標準適合の良い例ではありません...)。
「NaN」は「数字ではありません」と仮定すると、「数字ではありません」というマイナス値はほぼ同じです。私は、NaN記号の意味があるとは思わない。 [this](https://en.wikipedia.org/wiki/IEEE_754-1985#NaN)を指定すると、 'NaN'はどちらの記号も持つことができます。 –
浮動小数点のWikipediaページでは、±NaN、NaNのみについて言及していませんが、±0と±無限大を区別します。したがって、渡された値が 'NaN'であれば、返すことができるのは' NaN'です。 –
... MSVCは符号ビットに応じて 'nan'または' -nan'を表示します。 –