MySQL浮点比较问题

Sha*_*aik 20 mysql floating-point comparison select-query

我通过在MySQL数据库模式中引入浮点列遇到了一个问题,即浮点值的比较并不总是返回正确的结果.

1 - 50.12
2 - 34.57
3 - 12.75
4 - ......(休息时间均小于12.00)

SELECT COUNT(*) FROM `users` WHERE `points` > "12.75"
Run Code Online (Sandbox Code Playgroud)

这让我回归"3".

我已经读过MySQL中浮点值的比较是一个坏主意,十进制类型是更好的选择.

我是否有希望继续使用float类型并使比较正常工作?

Dan*_*llo 25

你注意到下面的问题了吗?

CREATE TABLE a (num float);

INSERT INTO a VALUES (50.12);
INSERT INTO a VALUES (34.57);
INSERT INTO a VALUES (12.75);
INSERT INTO a VALUES (11.22);
INSERT INTO a VALUES (10.46);
INSERT INTO a VALUES (9.35);
INSERT INTO a VALUES (8.55);
INSERT INTO a VALUES (7.23);
INSERT INTO a VALUES (6.53);
INSERT INTO a VALUES (5.15);
INSERT INTO a VALUES (4.01);

SELECT SUM(num) FROM a;
+-----------------+
| SUM(num)        |
+-----------------+
| 159.94000005722 | 
+-----------------+
Run Code Online (Sandbox Code Playgroud)

其中0.00000005722一些行之间有额外的差异.因此,与初始化的值相比,其中一些值将返回false.

为避免浮点运算和比较问题,您应该使用DECIMAL数据类型:

ALTER TABLE a MODIFY num DECIMAL(6,2);

SELECT SUM(num) FROM a;
+----------+
| SUM(num) |
+----------+
|   159.94 | 
+----------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)

  • @Sharief:如果无法转换为`DECIAML`,我看到的唯一选择是允许对浮点比较有一定的容忍度,这样您就可以按如下方式编写查询:`SELECT COUNT(*) FROM users WHERE points > (12.75 + 0.001);`... 但是,如果准确度至高无上,则固定点`DECIMAL` 是可行的方法。`DECIMAL` 的另一种替代方法是使用按比例放大的整数值以表示您的百分数值:`5012` 而不是 `50.12`。在某些情况下,这可能是合适的。 (2认同)

nin*_*nja 5

我这样做

WHERE abs(value - 12.75)<0.001
Run Code Online (Sandbox Code Playgroud)

但我同意,任何语言都可以比较浮点相等性,如果存储的值等于您插入的确切数字值,则不应该有任何问题

由于只有两位小数和精确匹配的值,精度错误听起来并不是 MySQL 中此类不匹配的明显原因