6

MySQL データベースに、price という名前の DECIMAL(10,2) フィールドを持つ顧客請求書テーブルがあります。

これらの値をphpで取得して合計金額を計算すると、

例: スクリプト内

$totalAmount = 0; // initialised them to 

   while(records){              

       $amount = $inv_amount - ($pay_amount + $onamount); //float i guess. 2.22, 14.22
       $totalAmount = $totalAmount + $amount; //float i guess. 2.22, 14.22 ..etc

    }

最終的な量 0.01 にわずかな誤差がある場合echo $totalAmount;、しかし 20,000 前後の大きなデータセットを扱う場合、この誤差は 200+ など非常に大きくなります。

PHPでこれらの数値を使用して価格などを処理する場合、これを行う最も安全な方法は何ですか? それとも、浮動小数点データ型を扱うときに一般的な丸めエラーやそのようなものになる可能性がありますか?

使っている

round 
number_format

は、このタイプの金融アプリケーションに最適なソリューションですか?

4

7 に答える 7

11

確かに、浮動小数点数は正確ではありません。
セントで計算する (100 を掛けて整数で計算する) か、BC Mathを使用して文字列で計算します。

于 2012-06-20T07:39:13.630 に答える
4

これを試して:

$totalAmount = number_format($totalAmount, 2, '.', '');
于 2012-06-20T07:48:50.083 に答える
2

小数点以下 2 桁の精度が必要な場合:

  1. 値を 100 倍する
  2. あなたの操作を行います
  3. 100 で割り、必要number_formatに応じて使用する
于 2012-06-20T07:39:14.940 に答える
0

クエリまたはビューを使用してSQLレベルで計算を行うことをお勧めします。

まず、PHPで64ビット整数を使用するのは危険です。オーバーフローすると、フロートに切り替わり、精度が低下します。それがお金であるとき、問題はより深刻です。sqlを使用して列を正確に計算し、そこから値を取得する必要があります。お金は長いタイプであり、多くの場合、phpでフロートに変換され、phpエンジンのムードに応じて、人々は数セントを失うか勝ちます。PHPで10進型を使用することはできません。たとえ、100を掛けて整数として保持しても、オーバーフローのある長い数値は自動的に浮動小数点数に変換されます。10進数を使用する場合、またはフィールドをintに変換する場合は、MYSQLで値を計算します。

サーバーに32ビットCPUがある場合、WORDの長さは32ビットであるため、phpエンジンの整数は32ビット整数です。これにより、オーバーフローの可能性が高くなります。64ビットシステムでは、より快適に作業できます。

この場合、金銭的価値にラウンド関数を使用することはばかげて専門的ではありません。しないでください。

このドキュメントを読むことはあなたに大いに役立ちます。

整数のphpドキュメントは言う

整数オーバーフロー

PHPが整数型の範囲を超える数値に遭遇した場合、代わりに浮動小数点数として解釈されます。また、整数型の範囲を超える数になる操作は、代わりにfloatを返します。

SQLレベルで計算すると、マネータイプの精度が保証されます。マネータイプをphpに取得すると、float値になり、100を掛けて、後で100で割ることができますが、phpはストレージに32ビットのfloat数値を使用するため、オーバーフローのリスクが再び高まります。32ビットフロートを使用している場合、データフィールドが10進数であるのはなぜですか?ですから、そうすると一貫性がなくなります。32ビットの数値はまだそれほど大きくありません。32ビットのfloatは浮動小数点でその容量の一部を失うため、100を掛けると容量を超える可能性が高くなります。

SQLを使用する

于 2012-06-20T07:45:15.157 に答える
0

あなたが使用することができますnumber_format

例:(小数点以下 2 桁の場合)

$number = 12345.5667;
echo $result = number_format($number, 2);

roundまたは、MySql で関数を使用できます。

ROUND(number,2)
于 2012-06-20T07:49:01.253 に答える
0

しようとしたことがありますか

round(totalAmount, 2, PHP_ROUND_HALF_ODD);

最後の 10 進数が表示されます - 奇数の場合は切り捨て、偶数の場合は切り上げます

于 2012-06-20T07:39:37.550 に答える
0

まず、mysql で実行できるのに、なぜ php ループで合計するのでしょうか? さらに、最終結果が必要になったら、整数を 100 倍してから 100 で割るだけです。

于 2012-06-20T07:39:46.347 に答える