MySQL楼层函数意外结果

MySQL楼层函数意外结果,mysql,floor,Mysql,Floor,查询 CREATE TABLE table_name (col_a double(10,2), col_b double(10,2), col_c double(10,2)); INSERT INTO table_name VALUES(36.3, 0, 6.3); 结果 第一个选择的值=>下限(36.3-0-6.3)导致30 第二个选择的值=>FLOOR(col\u a-col\u b-col\u c)等于FLOOR(36.3-0-6.3)结果是29,但我希望30 为什么选择获取两个不同

查询

CREATE TABLE table_name (col_a double(10,2), col_b double(10,2), col_c double(10,2));
INSERT INTO table_name VALUES(36.3, 0, 6.3);
结果


第一个选择的值=>
下限(36.3-0-6.3)
导致
30

第二个选择的值=>
FLOOR(col\u a-col\u b-col\u c)
等于
FLOOR(36.3-0-6.3)
结果是
29
,但我希望
30


为什么选择获取两个不同的值?

这是MySQL在使用
double
float
类型时存在的一个已知问题,它们的内部存储方式与我们看到的不完全相同

如果阅读,您会发现建议的解决方法是使用
十进制
而不是
双精度
。您可以在下面的提琴中看到,当使用
decimal(10,2)
作为列类型时,所有操作都按预期进行:


您在select中输入的值将自动作为十进制,这就是结果正确的原因

SELECT FLOOR(36.3- 0 -6.3), FLOOR(col_a - col_b - col_c) AS calc, col_a, col_b, col_c 
FROM table_name LIMIT 1;
浮点类型没有准确存储,因此无法获得准确的结果。试试这个:

select 36.3 - 0 - 6.3

--Produces
30.0
因此,地板的输出为29

因为浮点值是近似值,而不是存储为精确值 如果在比较中试图将其视为精确值,则可能导致 问题。它们也受平台或实施的影响 依赖关系

来自

SQL语句中写入的浮点值可能不是 与内部表示的值相同

正如Tim所建议的,您应该使用十进制类型。

这是因为下限(-6.3)是7。因此它将变为29


您可以查看二进制浮点的更多详细信息。二进制浮点基于IEEE 754浮点和双精度标准

在数据类型为双精度的列中插入值36.3时,其存储为“
36.2999923706055
”,对于6.3->“
6.30000190734863

您可以从这里或从中转换

现在结果是'29.99999904632569'。 现在您在其上应用了地板,结果为“29”

FLOOR()返回不大于指定为参数的数字的最大整数值

地板(a柱-b柱-c柱)

返回给您答案的输出下限(29.99999904632569)->29

正如Tim所建议的,您应该使用Decimal类型,或者使用below查询

select 36.3E0 - 0E0 - 6.3E0

--Produces
29.999999999999996

输出:30

最有可能是由于浮点存储,结果是29.9999。。和地板结果在29,但我正在寻找一个可靠的来源。不!!这是数据类型的原因。有关更多详细信息,请参阅Tim Biegeleisen的答案
        SELECT FLOOR(36.3- 0 -6.3),(col_a - col_b - col_c) 
        AS calc, col_a, col_b, col_c 
        FROM table_name LIMIT 1;