2011-02-09 10 views
4

いくつかの普遍的な研究では、私はいくつかの数字を近似する必要があります - シリーズのオイラーのように。したがって、私は非常に小さな数字を追加する必要がありますが、私は精度に問題があります。数字が非常に小さい場合、結果には影響しません。Dで高精度計算を実行するには?

real s; //sum of all previous terms 
ulong k; //factorial 

s += 1.0/ k; 

各ステップの後、kはさらに小さくなりますが、10日後に、結果はもうchangeingされていないラウンドと2.71828

答えて

3

ネイティブタイプを使用して実行するソリューションが必要な場合は、常に同じ数の数値を加算して妥当な結果を得ることができます。これを行う1つの方法があり合計で2つの最小の数値を置き換える繰り返し、その後シリーズの最初のX項を計算し、することです:(。分ヒープが少し速く、このになるだろう)

auto data = real[N]; 
foreach(i, ref v; data) { 
    v = Fn(i); 
} 

while(data.length > 1) { 
    data.sort(); // IIRC .sort is deprecated but I forget what replaced it. 
    data[1] += data[0]; 
    data = data[1..$]; 
} 

return data[0]; 

+0

素晴らしいです。私はこのように試してみましょう! – NaN

9

固定精度浮動小数点型、ネイティブにあなたのCPUのでサポートされているもので立ち往生浮動小数点ユニット(floatdoublereal)は、与えられた例のように、精度の桁数を必要とする計算には最適ではありません。

問題は、これらの浮動小数点型は、そのようなデータ型で表現できる数値の長さを制限する有限の精度の桁数(実際には2進数)を持つことです。 floatタイプの制限は小数点第7位(例:3.141593)です。 doubleタイプは14に制限されます(例:3.1415926535898)。 realタイプも同様の制限があります(doubleよりわずかに多い)。

浮動小数点値に非常に小さな数値を追加すると、その数字が失われます。

float a = 1.234567f, b = 0.00000000
float c = a + b; 

writefln("a = %f b = %f c = %f", a, b, c); 

両方abが有効な浮動小数点値であり、個々に分離して精度の約7桁を保持:私たちは一緒に、次の2つのfloat値を追加するときに何が起こるかを見ます。追加したとき、それはフロートに戻って押し込んだばかりだので、しかし、唯一の最前面の7桁の数字が保存されています

1.23456700=> 1.234567|00=> 1.234567 
           ^^^^^^^^^^^ 
         sent to the bit bucket 

ab GETの添加から精度の細かい数字がオフにフラフラのでそうcaに等しいを終わります。

Here's another explanation of the conceptおそらく鉱山よりもはるかに優れています。


この問題に対する答えは任意精度の算術です。残念ながら、任意精度の算術演算のサポートはCPUハードウェアにはありません。したがって、(通常は)プログラミング言語ではありません。しかし、任意精度の浮動小数点型をサポートする多くのライブラリと、それらで実行したい数学があります。いくつかの提案については、this questionを参照してください。あなたはおそらくこの目的のためにD固有のライブラリを見つけることはできませんが、孤立して使用するのに十分なはずのCライブラリ(GMP、MPFRなど)がたくさんあります。それらのうちの1つのためのDバインディング。

2

既に言及したように、サードパーティ製の多精度浮動小数点演算ライブラリ(TangoまたはPhobosは任意の長さの整数演算用のモジュールしか持っていないと思います)を使用する必要があります。

dilは、MPFRを使用するDプロジェクトです。そこにバインディングがあるはずです。