为什么 59.95 可以精确存储在 double 中?

Why can 59.95 be stored exact in double?

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

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

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"

returns 行 id=1.

似乎double列可以精确存储59.95,虽然这个数字不能精确存储在二进制中。这怎么可能?

当 52.95 转换为 IEEE-754 binary32(用于 float)时,结果为 59.950000762939453125。转换为IEEE-754 binary64(用于double)时,结果为59.9500000000000028421709430404007434844970703125.

在语句 SELECT * FROM `test` where b = "59.95" 中,文本 59.95 被转换为 double,生成 59.9500000000000028421709430404007434844970703125.

尝试从 float 数据中 select 这不会产生任何结果,因为没有 float 数据具有值 59.9500000000000028421709430404007434844970703125。它的值只能是 59.950000762939453125.

尝试从 double 数据中 select 得到结果,因为 double 数据的值为 59.9500000000000028421709430404007434844970703125。

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

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