我用SELECT 0.1 + 0.2;
测试,用MySQL(MariaDB)查询,它返回了正确的答案
MariaDB [(none)]> SELECT 0.1 + 0.2;
+-----------+
| 0.1 + 0.2 |
+-----------+
| 0.3 |
+-----------+
1 row in set (0.000 sec)
浮点计算在大多数编程语言中都是不准确的,因为IEEE 754解释了here。
MySQL如何进行浮点计算,使其返回正确的答案?
我知道SQL 92是旧标准,但我很确定在较新的SQL标准版本中没有改变。
SQL 92定义
73)子条款6.12,
"<numeric value expression>"
:当两个操作数的数据类型相加时。减法,乘法或除法运算符是精确数字,结果的精度是实现定义的。“*75)子条款6.12,
"<numeric value expression>"
:当算术运算符的任一操作数的数据类型是近似数字时,结果的精度是实现定义的。“*
问题是:0.1
和0.2
在查询SELECT 0.1 + 0.2
中是近似的还是确切的?
答案是:你不知道数据库也无法知道。
因此,数据库将运行为MySQL和MariaDB引擎定义的实现,此接缝将作为DECIMAL(1,1)
数据类型进行处理
为什么Nick的答案会返回正确的值或带有表定义的预期值
SQL 92还定义了
隐式类型转换可以在表达式中进行,获取操作 tions,单行选择操作,插入,删除和更新。 可以使用CAST指定显式类型转换 运营商。
Nick通过在表中定义数据类型来完成。
编辑这个答案,因为我今天在MySQL的手册中找到了一些东西。
查询
SELECT (0.1 + 0.2) = 0.3
结果导入MySQL中的1
,这意味着MySQL使用精确的数值计算并尽可能使用Precision Math。所以MySQL确实知道0.1
,0.2
和0.3
在这里是精确的数据类型,需要计算精确,就像我在编辑之前所期望的那样。
这意味着查询
SELECT (0.1 + 0.2) = 0.3
会或多或少地在引擎盖下运行
SELECT CAST((0.1 + 0.2) AS DECIMAL(1, 1)) = CAST((0.3) AS DECIMAL(1, 1));
这只是MySQL在数据类型/格式选择中是智能的,因为您没有指定这些值是浮点数。试试这个:
create table test (f float);
insert into test values (0.1), (0.2);
select sum(f) from test
输出:
sum(f)
0.30000000447034836
如果你使用双精度,你会得到经典的0.30000000000000004
结果。 Demo on dbfiddle