2017-05-12 3 views
1

私は、以下の、比較的簡単(非常に効率的ではないが)、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は標準適合の良い例ではありません...)。

+1

「NaN」は「数字ではありません」と仮定すると、「数字ではありません」というマイナス値はほぼ同じです。私は、NaN記号の意味があるとは思わない。 [this](https://en.wikipedia.org/wiki/IEEE_754-1985#NaN)を指定すると、 'NaN'はどちらの記号も持つことができます。 –

+0

浮動小数点のWikipediaページでは、±NaN、NaNのみについて言及していませんが、±0と±無限大を区別します。したがって、渡された値が 'NaN'であれば、返すことができるのは' NaN'です。 –

+0

... MSVCは符号ビットに応じて 'nan'または' -nan'を表示します。 –

答えて

2

C標準は、附属書F(オプション)を除いて浮動小数点の動作を指定する場合には、laxであり、附属書Fを採用しないC標準に準拠するC実装は、指示どおりに動作します。

ただし、品質実装は、少なくともIEEE 754-2008(C標準の附属書Fに記載されているIEC 60559と同じです)に準拠しようとします。 IEEE 754-2008では、5.5.1節で、浮動小数点オペランド(NaNを含む)を無効にすると符号ビットが変更されると述べています。

+0

ありがとう! * abs(x)は浮動小数点オペランドxを同じフォーマットでデスティネーションにコピーし、符号ビットを0(正の値)に設定します*したがって、5.5.1からの抜粋は私の場合に直接当てはまります。私の質問への答えを要約すると、それは次のようになります:*はい、それは有効ですwrt C標準には適合しますが、(オプションの)IEEE 754-2008標準*には適合しません。 – anol

関連する問題