ホームページ  >  記事  >  バックエンド開発  >  PHPの精度計算問題

PHPの精度計算問題

单线程
单线程オリジナル
2020-05-07 15:35:03173ブラウズ

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。