提问人:Adam 提问时间:7/21/2020 最后编辑:BarmarAdam 更新时间:7/21/2020 访问量:49
为什么 59.95 可以精确地以双倍存储?
Why can 59.95 be stored exact in double?
问:
我在MySql中创建了一个新表。 5.7.27-0ubuntu0.18.04.1
该表包含一列和一列。两列都使用 IEEE 754 格式。我在两个字段中都存储了数字 59.95。该数字不能表示为二进制中的有限数字。double
a
float
b
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
该列似乎能够精确存储,尽管这个数字不能精确地存储在二进制中。这怎么可能?double
59.95
答:
当 52.95 转换为 IEEE-754 binary32 (用于 ) 时,结果为 59.950000762939453125。当它转换为 IEEE-754 binary64 (used for ) 时,结果为 59.95000000000000028421709430404007434844970703125。float
double
在语句中,文本被转换为 ,得到 59.9500000000000028421709430404007434844970703125。SELECT * FROM `test` where b = "59.95"
59.95
double
尝试从数据中选择此值不会产生任何结果,因为没有数据的值为 59.9500000000000028421709430404007434844970703125。它只能有值 59.950000762939453125。float
float
尝试从数据中选择此值会产生结果,因为数据的值可以是 59.9500000000000028421709430404007434844970703125。double
double
您可以通过根据转换为 的值进行选择来找到所需的数据,例如 。不幸的是,我不熟悉 SQL 语法,无法确定所需的确切语法。float
float
CAST('59.95' AS FLOAT)
另请注意,在 中发生舍入,导致结果为 5995000000(可在 中表示),而不是 5995000000.00000028421709430404007434844970703125(不是)。a*100000000
double
评论
a*100000000000000
5.99e15
Select a from ..
59.90
Select a-59
0.8999999999999986
评论
SELECT * FROM test where a = "59.95"