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


PHP PDO query returns inaccurate value for FLOAT fields

我猜这个问题以前出现过,但是我找不到我问题的答案。下面是一小段代码片段:

    $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),这段代码以前工作得很好。我不确定这里出了什么问题。你能给我指个正确的方向吗?谢谢!

根据浮点类型(近似值)- FLOAT, DOUBLE:

MySQL在存储值时执行四舍五入,因此如果您将999.00009插入FLOAT(7,4)列,则近似结果为999.0001

由于浮点值是近似值,而不是作为精确值存储,因此在比较中将它们视为精确值可能会导致问题。它们还受平台或实现依赖关系的影响。有关详细信息,请参见第C.5.5.8节,"浮点值的问题"

为了最大限度的可移植性,需要存储近似数值数据值的代码应该使用FLOATDOUBLE PRECISION,不指定精度或位数。

因此,在将1.8插入数据库时,MySQL将文字四舍五入为001.8000,并以binary32格式编码与该数字最接近的近似值:即0x3FE66666,其位表示: <>之前符号: 0有偏指数: 0b01111111= 127(表示包括+127的偏差,因此exp = 0)显著性: 0b[1.]11001100110011001100110^隐藏位,不以二进制表示存储= [1] 7999999523162841796875之前

等于:

<>之前(1) ^ 0 * 1.7999999523162841796875 * 2 ^ 0 = <1.7999999523162841796875 strong> 之前

这是MySQL返回给客户端的值。看起来AdoDB随后检查了列的数据类型并对结果进行了四舍五入,而PDO则没有。

如果您想要精确的值,您应该使用定点数据类型,例如DECIMAL

如果你想要准确的值,你必须使用DECIMAL字段类型而不是FLOAT
PDO和这一点关系都没有。这与计算机的工作原理有关。