Tenga en cuenta que la siguiente sección es relevante
        principalmente para versiones de MySQL anteriores a 5.0.3. A
        partir de la versión 5.0.3, MyQL realiza las operaciones
        DECIMAL con una precisión de 64 dígitos
        decimales, lo que debería resolver los problemas de
        imprecisión más comunes en lo que se refiere a columnas
        DECIMAL. Para las columnas
        DOUBLE y FLOAT los
        problemas siguen porque la inexactitud es la naturaleza básica
        de los números en coma flotante.
      
        Los números en coma flotante a veces causan confusión porque
        no son almacenados como valores exactos en la arquitectura de la
        computadora. Lo que puede ver en la pantalla no es el valor
        exacto del número. Los tipos de columna
        FLOAT, DOUBLE, y
        DECIMAL son de este tipo. Las columnas
        DECIMAL almacenan valores con precisión
        exacta porque se representan como cadenas de caracteres, pero
        los cálculos sobre valores DECIMAL, en
        versiones previas a 5.0.3, eran realizadas utilizando
        operaciones de coma flotante.
      
        El siguiente ejemplo (para versiones anteriores a 5.0.3 de
        MySQL) demuestra el problema. Muestra que incluso para los tipos
        de columna DECIMAL, los cálculos se realizan
        utilizando operaciones de coma flotante que están sujetas al
        error. (En todas las versiones de MySQL, tendría problemas
        similares si reemplazara las columnas DECIMAL
        con FLOAT).
      
mysql> CREATE TABLE t1 (i INT, d1 DECIMAL(9,2), d2 DECIMAL(9,2));
mysql> INSERT INTO t1 VALUES (1, 101.40, 21.40), (1, -80.00, 0.00),
    -> (2, 0.00, 0.00), (2, -13.20, 0.00), (2, 59.60, 46.40),
    -> (2, 30.40, 30.40), (3, 37.00, 7.40), (3, -29.60, 0.00),
    -> (4, 60.00, 15.40), (4, -10.60, 0.00), (4, -34.00, 0.00),
    -> (5, 33.00, 0.00), (5, -25.80, 0.00), (5, 0.00, 7.20),
    -> (6, 0.00, 0.00), (6, -51.40, 0.00);
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b
    -> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+-------+
| i    | a      | b     |
+------+--------+-------+
|    1 |  21.40 | 21.40 |
|    2 |  76.80 | 76.80 |
|    3 |   7.40 |  7.40 |
|    4 |  15.40 | 15.40 |
|    5 |   7.20 |  7.20 |
|    6 | -51.40 |  0.00 |
+------+--------+-------+
        El resultado es correcto. Aunque los cinco primeros registros
        aparentan no poder pasar la comparación (los valores
        a y b no parecen ser
        diferentes), lo son porque la diferencia entre los dos números
        se encuentra a partir del decimal número diez aproximadamente,
        dependiendo de la arquitectura de la computadora.
      
A partir de MySQL 5.0.3, usted obtendría únicamente el último registro en el resultado anterior.
        El problema no puede ser resulto utilizando funciones como
        ROUND() o similares, porque el resultado
        sigue siendo un número en coma flotante:
      
mysql> SELECT i, ROUND(SUM(d1), 2) AS a, ROUND(SUM(d2), 2) AS b
    -> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+-------+
| i    | a      | b     |
+------+--------+-------+
|    1 |  21.40 | 21.40 |
|    2 |  76.80 | 76.80 |
|    3 |   7.40 |  7.40 |
|    4 |  15.40 | 15.40 |
|    5 |   7.20 |  7.20 |
|    6 | -51.40 |  0.00 |
+------+--------+-------+
        Esta es la apariencia que los números en la columna
        a tienen al mostrarse más cifras decimales:
      
mysql> SELECT i, ROUND(SUM(d1), 2)*1.0000000000000000 AS a,
    -> ROUND(SUM(d2), 2) AS b FROM t1 GROUP BY i HAVING a <> b;
+------+----------------------+-------+
| i    | a                    | b     |
+------+----------------------+-------+
|    1 |  21.3999999999999986 | 21.40 |
|    2 |  76.7999999999999972 | 76.80 |
|    3 |   7.4000000000000004 |  7.40 |
|    4 |  15.4000000000000004 | 15.40 |
|    5 |   7.2000000000000002 |  7.20 |
|    6 | -51.3999999999999986 |  0.00 |
+------+----------------------+-------+
Dependiendo de la arquitectura de su computadora, usted puede que vea o no resultados similares. Diferentes procesadores pueden evaluar los números en coma flotante de manera diferente. Por ejemplo, en algunas máquinas usted podría obtener los resultados “correctos” multiplicando ambos argumentos por 1, como en el siguiente ejemplo.
Aviso: Nunca utilice este método en sus aplicaciones. No es un ejemplo de procedimiento fiable.
mysql> SELECT i, ROUND(SUM(d1), 2)*1 AS a, ROUND(SUM(d2), 2)*1 AS b
    -> FROM t1 GROUP BY i HAVING a <> b;
+------+--------+------+
| i    | a      | b    |
+------+--------+------+
|    6 | -51.40 | 0.00 |
+------+--------+------+
La razón por la que el ejemplo precedente parece funcionar es que en una máquina particular donde la prueba fue realizada, la aritmética de coma flotante del procesador redondea los números al mismo valor. No obstante, no hay ninguna regla que diga que un procesador deba hacerlo, así que este método no merece confianza.
La manera adecuada de hacer comparaciones en coma flotante es primero decidir una tolerancia aceptable para las diferencias entre los números y realizar entonces las comparaciones sobre el valor de tolerancia. Por ejemplo, si estamos de acuerdo en que los números en coma flotante deben ser considerados el mismo si están dentro de una precisión de uno sobre diez mil (0.0001), la comparación debería escribirse para encontrar diferencias mayores que el valor de tolerancia:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
    -> GROUP BY i HAVING ABS(a - b) > 0.0001;
+------+--------+------+
| i    | a      | b    |
+------+--------+------+
|    6 | -51.40 | 0.00 |
+------+--------+------+
1 row in set (0.00 sec)
De manera análoga, para obtener los registros en que los números son iguales, la comparación debería encontrar diferencias dentro del valor de tolerancia:
mysql> SELECT i, SUM(d1) AS a, SUM(d2) AS b FROM t1
    -> GROUP BY i HAVING ABS(a - b) <= 0.0001;
+------+-------+-------+
| i    | a     | b     |
+------+-------+-------+
|    1 | 21.40 | 21.40 |
|    2 | 76.80 | 76.80 |
|    3 |  7.40 |  7.40 |
|    4 | 15.40 | 15.40 |
|    5 |  7.20 |  7.20 |
+------+-------+-------+
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.

