2015-12-10 1 views
7

ハスケル(WindowsのHaskellプラットフォームからのghci 7.10.2)がQNAN (0/0 :: Double)のサインをC++で見たことに気付きました(テスト済みのMSVS C++ 2013およびcygwin gcc 4.9 2)。 Haskellは(0/0)のビットパターン0xfff8000000000000(そして - (0/0)は0x7ff8 ...を生成する)を生成する。これは、C++の実装から逆になっているようです。ここでハスケルがqnanとして(0/0)を設定する

を説明するためのテストプログラムです:

import Data.Word 
import Unsafe.Coerce 
import Text.Printf 

dblToBits :: Double -> Word64 
dblToBits = unsafeCoerce 

test :: Double -> IO() 
test d = putStrLn $ printf "%12f  0x%x" d (dblToBits d) 

go = do 
    test (0/0) 
    test (-(0/0)) 
    test (1/0) 
    test (-(1/0)) 

これは出力が得られます。

 NaN  0xfff8000000000000 <- I expect 0x7F...? 
     NaN  0x7ff8000000000000 <- I expect 0xFF...? 
Infinity  0x7ff0000000000000 
-Infinity  0xfff0000000000000 

注意を、無限大は大丈夫アウト動作しますが、NaNの者が反転しているようです。

  • この部分は、HaskellのNaNの定義されていないセマンティクスの一部ですか?私。 (0/0)は、ghcが必要とするNaNパターンを使用できることを意味しますか?それでは、Haskellで特殊なIEEEライブラリ4に頼らずに浮動小数点でQNANまたはSNANを指定する正確な方法がありますか?私はそれがナナの味であるかもしれないと思うかもしれないハードウェアのためのアセンブラを書いています。

  • 私は焼き付いていますか?unsafeCoerce?私はnoを持っていますハスケルフロートからビットとバックに変換する方法。

REFERENCES:

  1. MSVS 2013 <限界からC++ std::numeric_limits<double>::quiet_NaN()>0x7ff8000000000000を与えます。またcygwin gcc 4.9.2でテストされました
  2. std::numeric_limits::quiet_NaN符号ビットの意味がインプリメンテーションによって定義されていることを示します。ハスケルも同様の規則を持っていますか?
  3. Perl semanticsはIEEE
  4. ためのMSV C++
  5. 可能なHaskellのlibraryと一致しており、わずかに関連questionは、私は戻って落ちた同じunsafeCoerce非感覚を使用しています。

答えて

5

あなたはNaNをあまりにも多く求めています。 IEEE規格によれば、NaN上の符号ビットは何でもかまいません。したがって、コンパイラ、プロセッサ、または浮動小数点ライブラリは自由に自由に選択して、さまざまなコンパイラ、プロセッサ、ライブラリで異なる結果を得ることができます。

特に、このようなプログラムでは、定数フォールディングは、コンパイラの実行方法に応じて、ターゲット環境ではなくコンパイラによって実行されることを意味します。コンパイラはネイティブ浮動小数点命令を使用するか、代わりにGMPやMPFRのようなものを使用することがあります。これは珍しいことではありません。 IEEE規格では符号ビットについては何も言及していないので、実装ごとに異なる値になります。最適化をオンまたはオフにしたときに値が変更されたことを実証できれば、-ffast-mathなどのではないことを完全に驚くことはありません。

最適化の例として、コンパイラは、NaNを計算しているを知っています。後で符号ビットを反転しないようにすることもできます。これはすべて一定の伝播を通じて起こります。他のコンパイラはそのような解析をしないので、符号ビットを反転するよう指示します。プロセッサを作った人は、その演算をNaNのために別々に動作させません。

つまり、NaNの符号ビットを理解しようとしないでください。

ここでは正確に何を達成しようとしていますか?

+0

これは私が掘り下げたものです。私は、IEEEのNaNで定義されていない符号ビットは、私がこれを別の方法で取り除いて解決するのに十分だと思います。 – Tim

+0

あなたは何を解決しようとしていますか? –

+0

基本的に私は、ツールのAとツールBを持っていて、どちらも命令のエンコーディングで "nan"をいくつかのビットパターンに変換します。ハードウェアは両方を処理する必要がありますが、ツールBを使用してツールAをテストするには、同じビットを生成する必要があります。したがって、私は、通常の抽象化境界を過ぎたもので悩まなければならない。 – Tim

関連する問題