php の精度計算の問題
PHP の興味深い現象を見てみましょう: var_dump( intval(0.58 * 100) ); このコードがどのような結果を出力すると思いますか?
出力結果は58ではなく57です
これはなぜですか?これはすべて浮動小数点演算によって引き起こされます。
実際、これらの結果は言語のバグではなく、言語の実装原理に関連しています。整数を含むすべての数値は、実際にはすべて倍精度 (double) 型です。
そして、PHP は int と float を区別します。どの言語であっても、浮動小数点演算を伴うものであれば同様の問題があるので、使用する際には注意が必要です。
浮動小数点数は、64 ビット長 (倍精度) を例として、1 つの符号ビット (E)、11 の指数ビット (Q)、および 52 の仮数ビット (M) で表されます (合計 64
符号ビット: 最上位ビットはデータの符号を表し、0 は正の数を表し、1 は負の数を表します。
指数ビット: データの累乗を基数 2 で表し、指数はオフセット コードで表されます。
仮数: データの小数点以下の有効桁を表します。
ここでの重要な点は、 2 進数での 10 進数の表現についてはどうですか? 2 進数で表現すると、Baidu で検索できます。ここでは詳しく説明しませんが、理解する必要があるのは、2 進数表現の場合、0.58 は無限に長い値であるということです。次の数値は暗黙の 1) を省略します。 10101110000101000 1111010111000010100011110
そして、この 2 つの 2 進数は、これらの 52 ビットのみで計算すると、次のようになります:
0.58 -> 0.579999999999999960.57 -> 0.5699999999999999
0.58 * 100 の具体的な浮動小数点乗算については、詳しくは考慮せず、ただ見ていきます。暗算で漠然と... 0.58 * 100 = 57.9999999 99
それでは intval をお願いします、当然 57 です...
この問題の重要な点は次のとおりであることがわかります。しかし、コンピュータのバイナリ表現では無限です。
PHP 浮動小数点型のパフォーマンスは +-*%/ 不正確さの問題があります
浮動小数点演算の不正確さの問題は、次の一般的に使用される高精度の方法で解決できます。 -精度関数:bcadd — 2つの高精度数値を加算する bccomp — 2つの高精度数値を比較する Number、-1, 0, 1を返す
bcdiv — 2つの高精度数値を除算する
bcmod — を求める高精度の数値の剰余
bcmul — 2 つの高精度の数値を乗算します
bcpow — 高精度の数値を求めます べき乗
bcpowmod — 高精度の数値の累乗を求め、数値で非常に一般的に使用される係数を求めます理論
bcscale — Linux bc の「scale=」に相当する、デフォルトの小数点以下の桁数を設定します
bcsqrt — 高精度の数値の平方根を求めます
bcsub — 2 つの高精度の数値を減算します
以上がPHPの精度計算問題の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。