美文网首页
PHP浮点数精度问题

PHP浮点数精度问题

作者: 皮儿吃屁 | 来源:发表于2020-09-08 16:29 被阅读0次

    PHP常见的浮点数“bug”

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

    浮点数的表示形式

    浮点数的表示(IEEE 754):

    • 浮点数, 以64位的长度(双精度)为例, 会采用1位符号位(E), 11指数位(Q), 52位尾数(M)表示(一共64位).
    • 符号位:最高位表示数据的正负,0表示正数,1表示负数。
    • 指数位:表示数据以2为底的幂,指数采用偏移码表示
    • 尾数:表示数据小数点后的有效数字.

    小数的二进制表示方式

    下面我们具体计算一下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

    相关文章

      网友评论

          本文标题:PHP浮点数精度问题

          本文链接:https://www.haomeiwen.com/subject/ipndektx.html