17 pontos por darjeeling 2026-01-25 | Ainda não há comentários. | Compartilhar no WhatsApp

Resumo:

  • O novo algoritmo de conversão de ponto flutuante proposto por Russ Cox é mais simples e, ao mesmo tempo, oferece melhor desempenho do que algoritmos complexos existentes (Ryū, Dragonbox etc.).
  • Por meio do primitivo central Unrounded Scaling, ele acelera a conversão entre binário e decimal para um nível equivalente a uma única multiplicação de 64 bits.
  • A implementação deve ser incluída no Go 1.27 (previsto para agosto de 2026) e oferece suporte tanto a saída de precisão fixa quanto a parsing/saída de menor comprimento que preserva o valor original.
  • Melhoria de desempenho em relação às implementações existentes
  • Desempenho de saída (Printing): melhora de cerca de 10~30%
  • Desempenho de parsing (Parsing): melhora de cerca de 5~15%

Resumo detalhado:

1. Contexto: a complexidade crônica da conversão de ponto flutuante

A tarefa de converter números de ponto flutuante binários do computador para decimais legíveis por humanos, ou fazer o caminho inverso, é uma área em que diversos algoritmos (Dragon4, Grisu3, Ryū, Dragonbox etc.) competem há décadas. No passado, Russ Cox disse que “converter é fácil, o problema é a velocidade”, mas neste post ele demonstra que “um algoritmo de conversão rápido também pode ser simples”.

2. Ideia central: Unrounded Numbers (⟨x⟩)

A base desse algoritmo é o tipo unrounded. Ele mantém não apenas a parte inteira do número, mas também 2 bits de informação adicional que incluem os dados necessários para arredondamento (o bit de ½ e o valor OR dos bits abaixo dele, chamado de 'sticky bit').

  • Estrutura: ⟨x⟩ = ⌊4x⌋ | (4x ≠ ⌊4x⌋)
  • Vantagem: ao manter essa forma, é possível executar operações como floor, ceil ou a mais importante em ponto flutuante, 'Round-to-nearest, ties-to-even', com custo muito baixo.

3. Escalonamento não arredondado rápido (Fast Unrounded Scaling)

A função mais importante é uscale(x, e, p). Ela calcula o resultado unrounded.
Algoritmos anteriores exigiam operações com inteiros muito grandes, mas esta abordagem processa isso dentro de operações de 64 bits com base no seguinte princípio.

// Exemplo de implementação conceitual (a versão otimizada real é mais complexa)  
func uscale(x uint64, e, p int) unrounded {  
    // Calcula aproximando 10^p como 2^k * fração exata  
    // Na maioria dos casos, reduz-se a uma única multiplicação de 64 bits (mul64) e operações de shift  
}  
  

4. Principais resultados e desempenho

  • Simplicidade: o código de implementação é muito curto, o que facilita a manutenção e permite prova lógica.
  • Desempenho: segundo os benchmarks, ele apresenta desempenho superior aos algoritmos considerados os mais rápidos atualmente, Dragonbox (saída) e Eisel-Lemire (parsing).
  • Versatilidade: aplica-se tanto à saída em ponto fixo (Fixed-width printing) quanto à saída de menor largura que recupera perfeitamente o valor original (Shortest-width printing).

5. O que isso significa para desenvolvedores

Esse algoritmo deve ser integrado à biblioteca padrão da linguagem Go. Quando a conversão decimal ocorrer internamente (por exemplo, fmt.Printf("%f", f) ou strconv.ParseFloat), desenvolvedores poderão obter resultados corretos usando menos recursos de CPU. Além disso, o conceito de unrounded oferece inspiração para um controle numérico preciso mesmo sem bibliotecas complexas de análise numérica.

Ainda não há comentários.

Ainda não há comentários.