2010-11-27 17 views
0

私はまだ正確な結果を得ることができません。最大値は何ですか?できるだけ正確に表示したい場合は、小数点以下を表示する必要がありますか?最大値は何ですか?浮動小数点数を表示する小数点以下の桁数(PHP)

いくつかのコード(コピー&ペーストしてテストする準備ができて):

// Test with 5 decimals 
$a = 0.00001; 
echo bcadd($a,$a,5) . '<br/>'; 
echo bcadd($a,$a,6) . '<br/>'; 
echo number_format(bcadd($a,$a,5),5) . '<br/>'; 
echo number_format(bcadd($a,$a,5),6) . '<br/>'; 
echo bcadd(0.00001,0.00001,20) . '<br/>'; 
echo number_format(bcadd($a,$a,20),5) . '<br/>'; 
echo number_format(bcadd($a,$a,20),21) . '<br/><br/>'; 

/* Output: 
0.00000 
0.000000 
0.00000 
0.000000 
0.00000000000000000000 
0.00000 
0.000000000000000000000 
*/ 

// Test with 4 decimals 
$a = 0.0001; 
echo bcadd($a,$a,5) . '<br/>'; 
echo bcadd($a,$a,6) . '<br/>'; 
echo number_format(bcadd($a,$a,5),5) . '<br/>'; 
echo number_format(bcadd($a,$a,5),6) . '<br/>'; 
echo bcadd(0.00001,0.00001,20) . '<br/>'; // wtf? this outputs 0 too? 
echo number_format(bcadd($a,$a,20),5) . '<br/>'; 
echo number_format(bcadd($a,$a,20),21) . '<br/>'; 

/* Output: 
0.00020 
0.000200 
0.00020 
0.000200 
0.00000000000000000000 
0.00020 
0.000200000000000000010 
*/ 

私は答えは4であることを推測すべき?しかし、私はまだコメントの行に問題がある

編集:私は誰も私のテストを理解したとは思わない。私はフロートが不正確であることを知っています。しかし1つは1!= 0.98990123で、他のものは1!= 0.0000です。 bc *関数の精度として4を設定すると、0.0000ではなく、0.9899以上(完全な答えが1の場合)になると予想されます。 1つは「無限精度では完全に正確ではありません」、もう1つは「まったく役に立たない」です。

編集2:@Michael Borgwardtは最大でどのような解決策

+2

は、あなたが必要とする限り、私は実際には問題が何であるかを理解していません。浮動小数点数は、バイナリに変換されるため正確ではありません。 –

+1

あなたのコメント行は5小数点以下を使用します。 – vakio

答えて

2

あなたの問題の主な原因は、あなたがフロートリテラルを使用していることです。コードがコンパイルまたは解釈され、binary fractionに変換されると、丸め誤差が発生します。

この時点で、あなたはすでに失われています - bcの数学関数を使用すると助けになりません。正しくそれらを使用するには、文字列リテラルを使用する必要があります。

echo bcadd('0.00001','0.00001',20); 

が印刷されます:

0.00002000000000000000 
+0

ありがとう!あなたは私の問題を理解した唯一の人です=) – HappyDeveloper

4

を持っています。できるだけ正確に表示したい場合は、小数点以下を表示する必要がありますか?

問題は浮動小数点計算から正確な値を取得しようとすることから始まります。表現エラーのために、一般的に浮動小数点計算から正確な値を得ることはできません。値0.0001はバイナリ浮動小数点で正確に表現することはできませんので、実際に格納されている値は0.0001とわずかに異なり、すでに不正確です。最下位の数字が不正確になることが予想されるはずです。より多くの小数点を表示しても、計算がより正確になるわけではありません。固有の不正確さを目立たせるだけです。

精度が必要な場合は、別のデータ型を使用するか(bcaddは文字列を受け入れますが、floatから文字列への変換でも不正確さが生じる可能性があります)、プログラムを変更して、正確な答え。

便利な回答を表示したい場合は、アプリケーションに適した精度で表示できます。あなたが七面鳥を調理するためにオーブンを設定するために温度を計算している場合、重要な数字のカップルへの答えを丸めても問題ありません。あなたが科学的な計算をしているなら、3、4、またはそれ以上の有効数字の回答を表示したいかもしれません。 100%の精度が必要な場合は、デザインを再考する必要があります。

+1

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems –

+0

@Alberto:http://floating-point-gui.de/ –

3

"bcadd"には3つの引数が必要です。最初の2つは、左右のオペランドを表す文字列と、結果の小数点以下の桁数を表す1つの整数です。この関数は文字列を出力します。 5番目の結果エコーで整数の代わりに文字列値を使用してみてください。 (PHP.netから)浮動小数点数の精度についても

おおよそ14桁の精度〜1.8e308の最大値であるが、フロートのサイズは、プラットフォーム依存であります共通の値(64ビットIEEE形式)。

+0

+1 @HappyDeveloper:マニュアルページはこちら[http:// php.net/manual/en/language.types.float.php)。 – netcoder

+0

あなたの答えは良いですが、bcaddがすでに3つの引数を使っているときに、3つの引数を取ると言って起動してはいけません。とにかくありがとう! – HappyDeveloper

+0

@HappyDeveloper:最初の2つは文字列でなければならないという事実を補強していただけです。 –

-1

BCMathライブラリを使用してみてください。基本的には数値を文字列として保存しますが、算術演算を行うことができます。

Handling Very Large or Very Small Numbers

+0

彼は* bc数学関数を使用しています - 間違っています。 –

+0

彼はBCMathライブラリを使用しています。したがって、 "bcadd"。 –

関連する問題