MySQL FLOOR函数意外结果

时间:2017-01-03 05:17:48

标签: 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);

enter image description here

QUERY

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;

RESULT

enter image description here

首选值=> FLOOR(36.3- 0 -6.3)会产生30

第二个选定值=>等于FLOOR(col_a - col_b - col_c)的{​​{1}}会产生FLOOR(36.3- 0 -6.3),但我期待29

为什么这些选择获得两个不同的值?

4 个答案:

答案 0 :(得分:4)

使用doublefloat类型时,这是MySQL中的一个已知问题,这些类型并非完全按照我们的内容存储在内部。

如果您阅读了MySQL documentation,则会找到建议的解决方法,即使用decimal代替double。在使用decimal(10,2)作为列类型时,您可以在以下小提琴中看到所有内容都按预期工作:

SQLFiddle

答案 1 :(得分:2)

您在选择中输入的值将自动视为小数,这就是结果正确的原因。

select 36.3 - 0 - 6.3

--Produces
30.0

浮点类型未完全存储,因此您无法获得准确的结果。试试这个:

select 36.3E0 - 0E0 - 6.3E0

--Produces
29.999999999999996

因此楼层在输出中给出了29。

来自https://dev.mysql.com/doc/refman/5.5/en/floating-point-types.html

  

因为浮点值是近似值而不是精确存储   价值,试图在比较中对待它们可能会导致   问题。它们也受平台或实施的约束   的依赖关系。

来自https://dev.mysql.com/doc/refman/5.5/en/problems-with-float.html

  

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

正如Tim建议的那样,你应该使用Decimal类型。

答案 2 :(得分:0)

这是因为楼层(-6.3)是7。因此它将变为29。

您可以查看https://msdn.microsoft.com/en-us/library/ms178531.aspx

的详细信息

答案 3 :(得分:0)

二进制浮点它基于IEEE 754标准的float和double。

当您将值36.3插入到数据类型为double的列中时,其存储为' 36.29999923706055'并且对于6.3 - > ' 6.300000190734863'

您可以从此处转换Link 1Link 2

现在结果col_a - col_b - col_c是' 29.99999904632569'。 现在你在它上面应用了地板,为你提供结果' 29'

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

floor (col_a - col_b - col_c)

返回输出楼层(29.99999904632569),它给你答案 - > 29

正如Tim建议的那样,您应该使用Decimal类型或使用以下查询。

        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;

输出:30