2011-07-12 5 views
2

私が知る限り、浮動小数点数は14個の数値を正確に表すことができます。浮動小数点はいつ登場するのですか?

それでは、私たちは

a = 564214623154 
b = 54252 

を持っているとしようと、私たちはこの C = * Bを掛け、それが30609771735350808でなければなりませんが、コンパイルされたときに、私はそれはいくつかを失う必要があります理解し、それはので、私3.0609771735351E + 16 を示し精度が、私は C/aでCを分割するとき、私は任意の精度なし564214623154正確な結果を得るには、別の例では、我々は

c = 30609771735350808 
d = 30609761111111111 
を持って言うことができます

を失いました

E = C-Dは10624239697する必要がありますが、コンパイルしたとき、それはとても精度が

を失っている私10624239696を示しだから、精度が、私は2つの数値を減算または追加した場合にのみ失われているのですか?

私がまた、乗算や除算の精度が失われる可能性があり、PHP

答えて

1

を使用して問題になります。 PHPとJavaScriptのストア番号は、52ビットの仮数と11ビットの指数を持つIEEE-754形式です。いくつかの整数は正確に表現され、いくつかは表現されません。

のは、これらを試してみましょう:

実数学(ルビーで生成)には:PHPとJavaScript

45345657434523 * 9347287748322342/74387422372 = 5697991604786167788 

45345657434523 * 9347287748322342/74387422372 = 5697991604786168000 

だから我々はまた、乗算、除算精度を失います。

編集:OPの質問に戻ってみると、結果には十五桁以上の精度が含まれていたため、これはすばらしい答えではないようです。問題の目的が、15桁の精度で表現された数の束を掛け算して除算するかどうかである場合、最終結果は、オーバーフローまたはアンダーフローしない限り、正確な精度を維持する傾向があります。 。したがって、1.25E35 * 2.5E7を掛けて正確に3.125e+42にすることができます。これは、PHPとJavaScriptが基本的に有効数字のグループを掛けて指数を加算するためです。ただし、これらの2つの値を加算すると1.25E35 + 2.5E7 = 1.25E35となります。それは正しいです、あなたは数に2500万を追加し、それは変化しません!これは、OPが言っているように、あなたは14または15桁の精度しか得られないからです。 120000000000000000000000000000000000 + 25000000を書き出して、これら2つの値を手動で追加してみてください。 14〜15桁は左から数え始めます。あなたはそれらをすべて選ぶことができません。

ボトムラインは、加算と減算で発生する可能性が高い精度です。知っておいてよかったです。

+1

IEEE754の隠れビットを忘れないでください。あなたは実際に53の使用可能な仮数を持っています。 –

+1

@Kerrek - ありがとうございます、はい53使用可能です。 @Templar - http://en.wikipedia.org/wiki/IEEE_754-1985は、他のページの場合は、Google、ieee 754から始めるのに適しています。 –

1

最初のケースで精度が失われた場合、PHPは浮動小数点数として大きな数値を書式設定するだけです。 (内部番号はfloatとして保持されます。)これは、「正確な」出力取りに行くしてみてください。c * dの場合には、アップ

$a = 564214623154; 
$b = 54252; 
$c = $a * $b; 
printf("%u, %u\n", $c, $c/$a); 

次へ]を、あなたの二つの数を個別にすでに標準の容量を超えIEEE- 64ビットの浮動小数点(53ビットですが、少なくとも55を必要とします)、これらの数値を格納すると、精度は既に失われています。

加減算の間に精度が失われるという問題は、「キャンセル」と呼ばれます。すべての記憶領域を消費した最上位ビットがすべて取り消され、マニッツァを埋めるのに十分なビットが足りなくなります。 C'est la vie。

あなたは月に座っており、英国ウスターの兄弟のひげ髪の長さを2回測定したとします。 2つの測定値を比較すると、非常に大量の精度を保存するという要件があります。

+0

@Templar:私はまさにそれをしています: '$ c'を整数として扱い、整数のように出力します。数値が内部的に倍精度として格納されている場合は、通常の量の塩でそれを取らなければなりません。つまり、値が表示されている桁数ほどではない場合があります。 –

関連する問題