どうやらあなたの算術エラーはすぐにはわかりません。それを詳しく説明させてください。
ダブルに大きな部分と小さな部分の2つの部分があり、それぞれが約32ビットの精度であるとします。(これは、doubleがどのように機能するかを正確に示しているわけではありませんが、私たちの目的には役立ちます。)
フロートは1つの部分しかありません。
一度に32ビットで実行していましたが、すべてを2倍にしたと想像してください。
double divisor = whatever;
double dividend = dividendbig + dividendlittle;
double bigquotient = dividendbig / divisor;
bigquotientとは何ですか?ダブルです。つまり、2つの部分があります。bigquotientは、bigquotientbig+bigquotientlittleと同じです。続行:
double littlequotient = dividendlittle / divisor;
繰り返しますが、littlequotientはlittlequotientbig+littlequotientlittleです。次に、商を追加します。
double quotient = bigquotient + littlequotient;
それをどのように計算しますか?商には2つの部分があります。quotientbigはbigquotientbigに設定されます。quotientlittleはbigquotientlittle+littlequotientbigに設定されます。littlequotientlittleは破棄されます。
ここで、フロートでそれを行うと仮定します。あなたが持っている:
float f1 = dividendbig;
float f2 = dividendlittle;
float r1 = f1 / divisor;
OK、r1とは何ですか?フロートです。したがって、それは1つの部分しかありません。r1はbigquotientbigです。
float r2 = f2 / divisor;
r2とは何ですか?フロートです。したがって、それは1つの部分しかありません。r2はlittlequotientbigです。
double result = (double)r1 + (double)r2;
それらを足し合わせると、bigquotientbig+littlequotientbigが得られます。 bigquotientlittleはどうなりましたか? そこでは32ビットの精度が失われているため、途中で32ビットが不正確になるのは当然のことです。 あなたは、32ビットで64ビット演算を概算するための正しいアルゴリズムをまったく思い付いていません。
を計算するために(big + little)/divisor
、単純に行うことはできません(big / divisor) + (little / divisor)
。この代数の規則は、すべての除算 中に丸める場合には適用されません。
それは今明らかですか?