MySQL FLOOR function unexpected results

核能气质少年 提交于 2019-12-07 08:32:25

问题


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);

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


first selected value => FLOOR(36.3- 0 -6.3) result in 30.

second selected value => FLOOR(col_a - col_b - col_c) which is equals to FLOOR(36.3- 0 -6.3) result in 29 but i am expecting 30

Why these selects getting two different values?


回答1:


This is a known problem in MySQL when using the double or float type, which are not stored internally exactly as we see them.

If you read the MySQL documentation, you will find a suggested workaround which is to use decimal instead of double. You can see in the following Fiddle that all is working as expected when using decimal(10,2) as your column types:

SQLFiddle




回答2:


The values you put in the select are automatically taken as decimal and that's why the result is correct.

select 36.3 - 0 - 6.3

--Produces
30.0

Floating point types are not stored exactly, so you'll not get the exact results. Try this:

select 36.3E0 - 0E0 - 6.3E0

--Produces
29.999999999999996

and hence floor gives you 29 in the output.

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

Because floating-point values are approximate and not stored as exact values, attempts to treat them as exact in comparisons may lead to problems. They are also subject to platform or implementation dependencies.

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

A floating-point value as written in an SQL statement may not be the same as the value represented internally.

As Tim advised, you should use Decimal type instead.




回答3:


This is because floor(-6.3) is 7 .Hence it will become 29.

Further details you can check on https://msdn.microsoft.com/en-us/library/ms178531.aspx




回答4:


Binary floating point it is based on the IEEE 754 standard for float and double.

when you insert value 36.3 into the column which has datatype double then its stores as '36.29999923706055' and for 6.3 - > '6.300000190734863'

You can convert from here Link 1 or Link 2

Now Result col_a - col_b - col_c is '29.99999904632569'. Now you applied floor on it which give you result '29'

FLOOR() returns the largest integer value not greater than a number specified as an argument.

floor (col_a - col_b - col_c)

Returns output floor(29.99999904632569) which give you answer - > 29

As Tim advised, you should use Decimal type instead or use below query.

        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;

Output : 30



来源:https://stackoverflow.com/questions/41436844/mysql-floor-function-unexpected-results

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!