Saltar al contenido principal
Si necesitas cálculos precisos, especialmente si trabajas con datos financieros o empresariales que requieren una alta precisión, deberías considerar usar Decimal en su lugar.Los números de coma flotante pueden dar lugar a resultados imprecisos, como se muestra a continuación:
CREATE TABLE IF NOT EXISTS float_vs_decimal
(
   my_float Float64,
   my_decimal Decimal64(3)
)
ENGINE=MergeTree
ORDER BY tuple();

# Generar 1 000 000 números aleatorios con 2 posición decimal y almacenarlos como float y como decimal
INSERT INTO float_vs_decimal SELECT round(randCanonical(), 3) AS res, res FROM system.numbers LIMIT 1000000;
SELECT sum(my_float), sum(my_decimal) FROM float_vs_decimal;

┌──────sum(my_float)─┬─sum(my_decimal)─┐
499693.60500000004499693.605
└────────────────────┴─────────────────┘

SELECT sumKahan(my_float), sumKahan(my_decimal) FROM float_vs_decimal;

┌─sumKahan(my_float)─┬─sumKahan(my_decimal)─┐
499693.605499693.605
└────────────────────┴──────────────────────┘
A continuación se muestran los tipos equivalentes en ClickHouse y en C:
  • Float32float.
  • Float64double.
En ClickHouse, los tipos Float tienen los siguientes alias:
  • Float32FLOAT, REAL, SINGLE.
  • Float64DOUBLE, DOUBLE PRECISION.
Al crear tablas, se pueden establecer parámetros numéricos para números de coma flotante (p. ej., FLOAT(12), FLOAT(15, 22), DOUBLE(12), DOUBLE(4, 18)), pero ClickHouse los ignora.

Uso de números de coma flotante

  • Los cálculos con números de coma flotante pueden producir errores de redondeo.
SELECT 1 - 0.9

┌───────minus(1, 0.9)─┐
0.09999999999999998
└─────────────────────┘
  • El resultado del cálculo depende del método de cálculo (el tipo de procesador y la arquitectura del sistema).
  • Los cálculos en coma flotante pueden dar lugar a valores como infinito (Inf) y “no es un número” (NaN). Esto debe tenerse en cuenta al procesar los resultados de los cálculos.
  • Al interpretar números de coma flotante a partir de texto, es posible que el resultado no sea el número representable por la máquina más cercano.

NaN e Inf

A diferencia del SQL estándar, ClickHouse admite las siguientes categorías de números de coma flotante:
  • Inf – Infinito.
SELECT 0.5 / 0

┌─divide(0.5, 0)─┐
│            inf │
└────────────────┘
  • -Inf — Infinito negativo.
SELECT -0.5 / 0

┌─divide(-0.5, 0)─┐
-inf │
└─────────────────┘
  • NaN — No es un número.
SELECT 0 / 0

┌─divide(0, 0)─┐
│          nan │
└──────────────┘
Consulte las reglas de ordenación de NaN en la sección cláusula ORDER BY.

Valores NaN en la semántica de conjuntos

El estándar IEEE 754 define NaN de modo que la comparación escalar NaN = NaN devuelve false. ClickHouse sigue esa regla para el operador =. Sin embargo, NaN no es un único valor; es cualquier patrón de bits cuyo exponente está compuesto solo por unos y cuya mantisa no es cero. Distintas operaciones y distintas arquitecturas de CPU pueden producir valores NaN con diferentes bits de signo o diferentes contenidos en la mantisa. Por ejemplo:
  • 0./0. produce un NaN cuyo bit de signo es 1 en la mayoría de las plataformas x86.
  • El literal nan produce un NaN cuyo bit de signo es 0.
  • Después de PR #98230, la ruta NEON de AArch64 para log devuelve un NaN cuyo bit de signo difiere del log escalar de glibc con entradas negativas.
Las tablas hash de ClickHouse comparan las claves byte a byte, por lo que distintos patrones de bits de NaN se asignan mediante hash a distintas cubetas y se tratan como valores distintos en operaciones con semántica de conjuntos, incluidas DISTINCT, GROUP BY, uniqExact, countDistinct y equi-JOIN sobre una clave Float:
SELECT countDistinct(arrayJoin([0./0., nan, log(-1.)]));
-- May return 2 or 3 depending on architecture and build, even though all three inputs are NaN.
Esto es coherente con IEEE 754 (cada NaN es distinto de cualquier otro valor, incluido él mismo), pero puede resultar sorprendente. Si necesita que las operaciones con semántica de conjuntos traten todos los valores NaN como iguales, llévelos a una forma canónica en la consulta:
-- Replace every NaN with a single canonical NaN value
SELECT countDistinct(if(isNaN(x), CAST('nan' AS Float64), x))
FROM (SELECT arrayJoin([0./0., nan, log(-1.)]) AS x);
-- Returns 1.

-- Or exclude NaN values from the set entirely
SELECT countDistinct(if(isNaN(x), NULL, x))
FROM (SELECT arrayJoin([0./0., nan, log(-1.)]) AS x);
-- Returns 0.
El mismo enfoque también se aplica a las claves de DISTINCT, GROUP BY y JOIN.

BFloat16

BFloat16 es un tipo de dato de coma flotante de 16 bits con exponente de 8 bits, bit de signo y mantisa de 7 bits. Es útil para aplicaciones de aprendizaje automático e IA. ClickHouse admite conversiones entre Float32 y BFloat16, que pueden realizarse mediante las funciones toFloat32() o toBFloat16.
La mayoría de las demás operaciones no son compatibles.
Última modificación el 25 de junio de 2026