2017-02-22 15 views
0

.NET doubleとpython floatの違いは何ですか? C#ので

Console.WriteLine(1.2d - 1.0d); 

0.2を生成します。 Python 3で:

print(1.2 - 1.0) 

0.19999999999999996を生成します。

私の目標は、Python 3と同じ浮動小数点結果を生成するC#で高速なコードを書くことです。私は明らかに上記の例だけでなく、すべての浮動小数点演算に興味があります。

これを達成する最も実用的な方法は何ですか?私が使用できるライブラリはありますか?

さらに、私はこの違いをどのように説明しているのか理解したいと思います。どちらの表現も64ビットで、両方ともIEEEに基づいているようです。では、異なる結果を生み出すこれらの実装についてはどういう違いがありますか?

参照:

+0

文字列表現ではなく、結果のビット単位の表現を見ることから始めてみることをお勧めします。これを行うまでは、減算結果が実際には異なるという証拠はありません。しかし、C#ではJITコンパイラがいくつかの算術演算でより正確な表現を使用できることも理解する必要があります。複数の64ビット演算を実行しながら80ビットの中間結果を使用する。プラットフォーム間でビット互換の算術演算をしたいのなら、それは難しいでしょう。 –

+0

@JonSkeet、ありがとうございます、これは悪いニュースです( –

+0

FWIW、Python 2の '0.2'で表示されますが、' d = 1.2-1.0; print(format(d 、 '0.60f')) 'どちらのバージョンでも' 0.199999999999999955591079014993738383054733276367187500000000'を出力する –

答えて

0

ジョンスキートは、COMMで指摘したようにビット表現を比較する必要があります。 C#で試してみてください:

Console.WriteLine($"{BitConverter.DoubleToInt64Bits(1.2d - 1.0d):X}"); 

結果:3FC9999999999998 python 3(this answerの礼儀)で今

import struct 
import binascii 
print(binascii.hexlify(struct.pack('>d', (1.2 - 1.0))).decode()) 

結果:3fc9999999999998

あなたが見ることができるように、結果は同じです。

+0

この場合、はいですが、複雑な計算を行っているときに中間結果に何が起こるかについての私のコメントの他の側面は、依然として関連しているかもしれません(恐らくPythonでも発生するかもしれませんが、 *発生時のルールは.NETでは実装固有です。) –

+0

@JonSkeetは理解しています。無関係なメモでは、同じビットが異なる数字として印刷されることをどのように説明できますか?出力用の倍精度の書式設定に使用される特定の(よく知られた)アルゴリズムはありますか? –

+1

.NETの場合、 'double.ToString()'を呼び出すことは、[G形式指定子](https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx)を使用するのと同じです。 #GFormatString) - 詳細はこちらを参照してください。私はあなたが使用できるクラス(http://jonskeet.uk/csharp/DoubleConverter.cs)を持っています。これは 'double'の* exact *値を出力します - Pythonで同等のものがあるかどうかわかりません。 –

関連する問題