Pular para o conteúdo principal
Se você precisa de cálculos precisos, especialmente se trabalha com dados financeiros ou de negócios que exigem alta precisão, considere usar Decimal.Números de ponto flutuante podem levar a resultados imprecisos, como ilustrado abaixo:
CREATE TABLE IF NOT EXISTS float_vs_decimal
(
   my_float Float64,
   my_decimal Decimal64(3)
)
ENGINE=MergeTree
ORDER BY tuple();

# Gere 1 000 000 números aleatórios com 2 casas decimais e armazene-os como float e 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
└────────────────────┴──────────────────────┘
Os tipos equivalentes no ClickHouse e em C são os seguintes:
  • Float32float.
  • Float64double.
Os tipos Float no ClickHouse têm os seguintes aliases:
  • Float32FLOAT, REAL, SINGLE.
  • Float64DOUBLE, DOUBLE PRECISION.
Ao criar tabelas, é possível definir parâmetros numéricos para números de ponto flutuante (por exemplo, FLOAT(12), FLOAT(15, 22), DOUBLE(12), DOUBLE(4, 18)), mas o ClickHouse os ignora.

Uso de números de ponto flutuante

  • Cálculos com números de ponto flutuante podem produzir erro de arredondamento.
SELECT 1 - 0.9

┌───────minus(1, 0.9)─┐
0.09999999999999998
└─────────────────────┘
  • O resultado do cálculo depende do método de cálculo (do tipo de processador e da arquitetura do sistema computacional).
  • Cálculos de ponto flutuante podem resultar em números como infinito (Inf) e “não é um número” (NaN). Isso deve ser levado em conta ao processar os resultados dos cálculos.
  • Ao interpretar números de ponto flutuante a partir de texto, o resultado pode não ser o número representável pela máquina mais próximo.

NaN e Inf

Ao contrário do SQL padrão, o ClickHouse oferece suporte às seguintes categorias de números de ponto flutuante:
  • Inf – infinito.
SELECT 0.5 / 0

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

┌─divide(-0.5, 0)─┐
-inf │
└─────────────────┘
  • NaN — Não é um número.
SELECT 0 / 0

┌─divide(0, 0)─┐
│          nan │
└──────────────┘
Consulte as regras de ordenação de NaN na seção cláusula ORDER BY.

Valores NaN na semântica de conjunto

O padrão IEEE 754 define NaN de modo que a comparação escalar NaN = NaN retorne false. O ClickHouse segue essa regra para o operador =. No entanto, NaN não é um único valor; ele pode ser qualquer padrão de bits em que o expoente é composto apenas por uns e a mantissa é diferente de zero. Operações diferentes e arquiteturas de CPU diferentes podem produzir valores NaN com bits de sinal diferentes ou payloads de mantissa diferentes. Por exemplo:
  • 0./0. produz um NaN cujo bit de sinal é 1 na maioria das plataformas x86.
  • O literal nan produz um NaN cujo bit de sinal é 0.
  • Após o PR #98230, o caminho NEON em AArch64 de log retorna um NaN cujo bit de sinal difere do log escalar da glibc para entradas negativas.
As tabelas hash no ClickHouse comparam chaves byte a byte, portanto padrões de bits NaN diferentes caem em buckets diferentes e são tratados como valores distintos por operações com semântica de conjunto, incluindo DISTINCT, GROUP BY, uniqExact, countDistinct e equi-JOIN em uma chave 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.
Isso está de acordo com a IEEE 754 (todo NaN é diferente de qualquer outro valor, inclusive de si mesmo) mas pode causar estranheza. Se você precisar que operações com semântica de conjunto tratem todos os valores NaN como iguais, normalize-os na 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.
A mesma abordagem funciona para as chaves de DISTINCT, GROUP BY e JOIN.

BFloat16

BFloat16 é um tipo de dado de ponto flutuante de 16 bits, com expoente de 8 bits, sinal e mantissa de 7 bits. Ele é útil para aplicações de aprendizado de máquina e IA. O ClickHouse oferece suporte a conversões entre Float32 e BFloat16, que podem ser realizadas com as funções toFloat32() ou toBFloat16.
A maioria das outras operações não tem suporte.
Última modificação em 25 de junho de 2026