微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PHP PDO查询返回FLOAT字段的不准确值

我猜这个已经出现了,但我找不到我的问题的答案.这是一个代码片段:

    $stmt = $this -> db -> query("
        SELECT
          `Field`
        FROM
          `Table`
        WHERE
          (`ID` = 33608)");
    var_dump($stmt -> fetch());

这是我得到的结果:

    array(1) { ["Field"]=> float(1.7999999523163) }

但是,MysqL数据库中的数据是1.8.字段的类型是float(7,4). $this-> db是一个PDO对象.
我最近迁移到PDO(来自AdoDB),此代码之前工作正常.我不确定这里出了什么问题.你能指出我正确的方向吗?
谢谢!

解决方法:

Floating-Point Types (Approximate Value) – FLOAT, DOUBLE所述:

MysqL performs rounding when storing values, so if you insert 999.00009 into a FLOAT(7,4) column, the approximate result is 999.0001.

Because floating-point values are approximate and not stored as exact values, attempts to treat them as exact in comparisons may lead to problems. They are also subject to platform or implementation dependencies. For more information, see 07001

For maximum portability, code requiring storage of approximate numeric data values should use FLOAT or DOUBLE PRECISION with no specification of precision or number of digits.

因此,在将1.8插入数据库时​​,MysqL文字四舍五入为001.8000,并以binary32格式编码与该数字最接近的近似值:即0x3FE66666,其位表示:

Sign           : 0b0

Biased exponent: 0b01111111
               =   127 (representation includes bias of +127, therefore exp = 0)

Significand    : 0b[1.]11001100110011001100110
                    ^ hidden bit, not stored in binary representation
               =   [1.]7999999523162841796875

这相当于:

 (-1)^0 * 1.7999999523162841796875 * 2^0
=         1.7999999523162841796875

这是MysqL返回给客户端的值.看来AdoDB会检查列的数据类型并相应地舍入结果,而PDO却没有.

如果需要精确值,则应使用fixed point datatype,例如DECIMAL.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐