Problemas de comparação de ponto flutuante do MySQL

Eu me deparei com um problema, introduzindo colunas de ponto flutuante no esquema de database MySQL que as comparações em valores de ponto flutuante não retornam os resultados corretos sempre.

1 – 50.12
2 a 34,57
3 – 12,75
4 – … (descanse tudo menos que 12.00)

SELECT COUNT(*) FROM `users` WHERE `points` > "12.75" 

Isso me retorna “3”.

Eu li que as comparações de valores de ponto flutuante no MySQL são uma idéia ruim e o tipo decimal é a melhor opção.

Tenho alguma esperança de avançar com o tipo float e fazer as comparações funcionarem corretamente?

Você percebe o problema abaixo?

 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 | +-----------------+ 

Há um spread extra de 0.00000005722 entre algumas dessas linhas. Portanto, alguns desses valores retornarão false quando comparados com o valor com o qual foram inicializados.

Para evitar problemas com aritmética de ponto flutuante e comparações, você deve usar o tipo de dados 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) 

Eu enfrentei o problema semelhante uma vez. Converta o campo ‘float’ em ‘decimal’. Isso definitivamente vai resolver o problema.

É um ponto flutuante, então qual é o problema? 3 poderia ser o resultado correto, depende do que o database pensa 12.75. É 12.75 ou apenas um pouco mais?

Use DECIMAL se você quiser números exatos.

Há um problema com a comparação de carros alegóricos por igualdade. Isso pode dar resultados imprevisíveis. Isso se deve à implementação interna da aritmética de ponto flutuante.

Eu faço isso

 WHERE abs(value - 12.75)<0.001 

mas eu concordo, qualquer linguagem pode comparar a igualdade de float e se valores armazenados forem iguais a valores de números exatos que você inseriu, não deve haver nenhum problema

com apenas alguns decimais e valores de correspondência exatos, erros de precisão não soam como uma razão óbvia para tais incompatibilidades no MySQL

Comparando um número com uma string?