MySQL 浮点数加法的数学计算是怎么做的?
How MySQL does the math calculation of floating point addition?
我用 SELECT 0.1 + 0.2;
进行了测试,用 MySQL (MariaDB) 进行了查询,return 给出了正确的答案
MariaDB [(none)]> SELECT 0.1 + 0.2;
+-----------+
| 0.1 + 0.2 |
+-----------+
| 0.3 |
+-----------+
1 row in set (0.000 sec)
由于IEEE 754 as explained here.
,大多数编程语言的浮点计算都不准确
如何MySQL进行浮点计算使其return成为正确答案?
这只是 MySQL 在数据 type/formatting 选择方面的智能,因为您没有指定这些值是浮点数。试试这个:
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
我知道 SQL 92 是旧标准,但我很确定这在较新的 SQL 标准版本中没有改变。
SQL 92 定义
73)Subclause 6.12, "<numeric value expression>"
: When the data type
of both operands of the addition. subtraction, multiplication,
or division operator is exact numeric, the precision of the
result is implementation-defined."*
75)Subclause 6.12, "<numeric value expression>"
: When the data
type of either operand of an arithmetic operator is approximate
numeric, the precision of the result is implementation-defined."*
问题是:查询SELECT 0.1 + 0.2
中的0.1
和0.2
是近似值还是精确值?
答案是:你不知道,数据库也不会知道。
因此数据库将 运行 为 MySQL 定义的实现和 MariaDB 引擎将此接缝处理为 DECIMAL(1,1)
数据类型
为什么 Nick 的回答 return 是正确的值或具有 table 定义的预期值
SQL 92 也定义了
Implicit type conversion can occur in expressions, fetch opera-
tions, single row select operations, inserts, deletes, and updates.
Explicit type conversions can be specified by the use of the CAST
operator.
Nick 通过在 table 中定义数据类型来完成。
编辑了这个答案,因为我今天在 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));
我用 SELECT 0.1 + 0.2;
进行了测试,用 MySQL (MariaDB) 进行了查询,return 给出了正确的答案
MariaDB [(none)]> SELECT 0.1 + 0.2;
+-----------+
| 0.1 + 0.2 |
+-----------+
| 0.3 |
+-----------+
1 row in set (0.000 sec)
由于IEEE 754 as explained here.
,大多数编程语言的浮点计算都不准确如何MySQL进行浮点计算使其return成为正确答案?
这只是 MySQL 在数据 type/formatting 选择方面的智能,因为您没有指定这些值是浮点数。试试这个:
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
我知道 SQL 92 是旧标准,但我很确定这在较新的 SQL 标准版本中没有改变。
SQL 92 定义
73)Subclause 6.12,
"<numeric value expression>"
: When the data type of both operands of the addition. subtraction, multiplication, or division operator is exact numeric, the precision of the result is implementation-defined."*75)Subclause 6.12,
"<numeric value expression>"
: When the data type of either operand of an arithmetic operator is approximate numeric, the precision of the result is implementation-defined."*
问题是:查询SELECT 0.1 + 0.2
中的0.1
和0.2
是近似值还是精确值?
答案是:你不知道,数据库也不会知道。
因此数据库将 运行 为 MySQL 定义的实现和 MariaDB 引擎将此接缝处理为 DECIMAL(1,1)
数据类型
为什么 Nick 的回答 return 是正确的值或具有 table 定义的预期值
SQL 92 也定义了
Implicit type conversion can occur in expressions, fetch opera-
tions, single row select operations, inserts, deletes, and updates.
Explicit type conversions can be specified by the use of the CAST
operator.
Nick 通过在 table 中定义数据类型来完成。
编辑了这个答案,因为我今天在 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));