Проблемы сравнения с плавающей запятой MySQL
Я столкнулся с проблемой, представив столбцы с плавающей запятой в схеме базы данных MySQL, что сравнения значений с плавающей запятой не всегда возвращают правильные результаты.
1 - 50,12
2 - 34,57
3 - 12,75
4 -... (все остальные менее 12.00)
SELECT COUNT(*) FROM `users` WHERE `points` > "12.75"
Это возвращает меня "3".
Я читал, что сравнение значений с плавающей запятой в MySQL - это плохая идея, а десятичный тип - лучший вариант.
Есть ли у меня какая-либо надежда на продвижение по типу с плавающей точкой и правильное выполнение сравнений?
Ответы
Ответ 1
Вы заметили проблему ниже?
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 |
+-----------------+
Там есть дополнительный 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)
Ответ 2
Я столкнулся с подобной проблемой один раз. Преобразуйте поле "float" в "decimal". Это определенно решит проблему.
Ответ 3
Я делаю это
WHERE abs(value - 12.75)<0.001
но я согласен, любой язык может сравнивать равенство float, и если сохраненные значения равны точным значениям чисел, которые вы вставили, не должно быть никаких проблем
только с несколькими десятичными знаками и точными значениями соответствия, точные ошибки не кажутся очевидной причиной таких несоответствий в MySQL
Ответ 4
Это плавающая точка, так что проблема? 3 может быть правильным результатом, зависит от того, что база данных думает о 12.75. Это 12,75 или немного больше?
Используйте DECIMAL, если вы хотите точные цифры.
Ответ 5
Есть проблемы с сопоставлением поплавков для равенства. Это может дать непредсказуемые результаты. Это связано с внутренней реализацией арифметики с плавающей запятой.
Ответ 6
Сравнение числа со строкой?
Ответ 7
Используйте REAL вместо FLOAT или DECIMAL.