为什么 59.95 可以精确地以双倍存储?

Why can 59.95 be stored exact in double?

提问人:Adam 提问时间:7/21/2020 最后编辑:BarmarAdam 更新时间:7/21/2020 访问量:49

问:

我在MySql中创建了一个新表。 5.7.27-0ubuntu0.18.04.1

该表包含一列和一列。两列都使用 IEEE 754 格式。我在两个字段中都存储了数字 59.95。该数字不能表示为二进制中的有限数字。doubleafloatb

float 列的输出如下所示:

SELECT b*100000000 FROM `test` where id=1

5995000076.293945

SELECT * FROM `test` where b = "59.95"

没有结果。两者都如预期。但是,对于双列,我得到以下结果:

 SELECT a*100000000 FROM `test` where id=1

5995000000

SELECT * FROM `test` where a = "59.95"

返回带有 的行。id=1

该列似乎能够精确存储,尽管这个数字不能精确地存储在二进制中。这怎么可能?double59.95

MySQL 浮点 精度

评论

1赞 Barmar 7/21/2020
它没有精确存储,但它有更多的数字,因此您无法轻易看到错误。
0赞 Adam 7/21/2020
@Barmar如果是这样的话,为什么要返回这一行呢?SELECT * FROM test where a = "59.95"
0赞 P.Salmon 7/21/2020
你读过 dev.mysql.com/doc/refman/8.0/en/type-conversion.html

答:

2赞 Eric Postpischil 7/21/2020 #1

当 52.95 转换为 IEEE-754 binary32 (用于 ) 时,结果为 59.950000762939453125。当它转换为 IEEE-754 binary64 (used for ) 时,结果为 59.95000000000000028421709430404007434844970703125。floatdouble

在语句中,文本被转换为 ,得到 59.9500000000000028421709430404007434844970703125。SELECT * FROM `test` where b = "59.95"59.95double

尝试从数据中选择此值不会产生任何结果,因为没有数据的值为 59.9500000000000028421709430404007434844970703125。它只能有值 59.950000762939453125。floatfloat

尝试从数据中选择此值会产生结果,因为数据的值可以是 59.9500000000000028421709430404007434844970703125。doubledouble

您可以通过根据转换为 的值进行选择来找到所需的数据,例如 。不幸的是,我不熟悉 SQL 语法,无法确定所需的确切语法。floatfloatCAST('59.95' AS FLOAT)

另请注意,在 中发生舍入,导致结果为 5995000000(可在 中表示),而不是 5995000000.00000028421709430404007434844970703125(不是)。a*100000000double

评论

0赞 Adam 7/22/2020
如何查看存储在 mysql 中的确切值?如果我尝试,我会得到.如果我这样做,我只会得到.我使用phpMyAdmin访问数据库a*1000000000000005.99e15Select a from ..59.90
0赞 Adam 7/22/2020
啊,如果我这样做,我会得到Select a-590.8999999999999986