PHP浮点数精度问题

2020-09-08  本文已影响0人  皮儿吃屁

PHP常见的浮点数“bug”

<?php
    $f = 0.58;
    var_dump(intval($f * 100)); //为啥输出57

浮点数的表示形式

浮点数的表示(IEEE 754):

小数的二进制表示方式

下面我们具体计算一下0.58的小数表示过程
0.58 * 2 = 1.16 —————— 1
0.16 * 2 = 0.32 —————— 0
0.32 * 2 = 0.64 —————— 0
0.64 * 2 = 1.28 —————— 1
0.28 * 2 = 0.56 —————— 0
0.56 * 2 = 1.12 —————— 1
0.12 * 2 = 0.24 —————— 0
……
0.58 对于二进制表示来说, 是无限长的值

0.58的二进制表示基本上(52位)是: 1001010001111010111000010100011110101110000101000111

如果0.58只是通过这52位计算的话是:

0.58 -> 0.57999999999999996

所以0.58 * 100 = 57.9999999……

精准的浮点数

    $x = 8 - 7.74;
    $y = 0.26;
    var_dump($x == $y); // false
    $x = 8 - 7.75;
    $y = 0.25;
    var_dump($x == $y); //  true

0.25的二进制表示0.01,0.26的二进制表示0.0100001……,所以0.25是精准的,而0.26不是。

参考:https://www.laruence.com/2013/03/26/2884.html

上一篇下一篇

猜你喜欢

热点阅读