我使用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如何计算使其返回正确答案的浮点数?
答案 0 :(得分:5)
我知道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)
数据类型
为什么尼克的答案会返回正确的值或带有表定义的期望值
SQL 92也定义了
隐式类型转换可以在表达式中进行,获取Opera-
动作,单行选择操作,插入,删除和更新。
可以使用CAST指定显式类型转换
运算符。
尼克通过定义表中的数据类型来做到这一点。
编辑此答案是因为我今天在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));
答案 1 :(得分:4)
那只是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