59 pontos por GN⁺ 2025-02-17 | 12 comentários | Compartilhar no WhatsApp

"App de calculadora? Qualquer um pode fazer" → na verdade, não é bem assim

  • Uma calculadora precisa mostrar com precisão o resultado de expressões matemáticas, e isso é muito mais difícil do que parece
  • Na calculadora do iOS, (10^100) + 1 − (10^100) é calculado incorretamente como 0
  • Já no Android, o resultado correto é 1, e a forma como isso foi feito é realmente impressionante

Google e Hans-J. Boehm

  • O Google contratou o renomado programador Hans-J. Boehm
  • Boehm é um especialista que definiu a semântica de variáveis compartilhadas em C++
  • Mas a missão que lhe deram foi, inesperadamente, desenvolver um app de calculadora

O problema do ponto flutuante

  • Números de ponto flutuante não conseguem representar com exatidão valores como 0.3 ou 10^100
  • Ou seja, uma calculadora baseada em ponto flutuante não é confiável
  • Para fazer cálculos exatos, é preciso outra abordagem

A solução com Bignum

  • O problema dos cálculos com inteiros pode ser resolvido usando Bignum (inteiros de precisão arbitrária)
  • Bignum é um tipo de inteiro que se expande dinamicamente conforme o tamanho da memória
  • O problema de (10^100) + 1 - (10^100) pode ser resolvido com Bignum
  • Mas isso não resolve operações com frações

Frações e números algébricos

  • Frações (valores como 3/4) podem ser tratadas armazenando numerador e denominador com Bignum
  • Porém, irracionais como pi (π) ou raiz quadrada de 2 (√2) não podem ser representados assim
  • Boehm tentou uma representação baseada em polinômios
    • Ex.: √2 pode ser representado pela equação x² - 2 = 0
    • Mas π não pode ser representado nem dessa forma

Números reais construtivos (Constructive Real Numbers)

  • Boehm explorou o conceito de "operações recursivas com reais (RRA)"
  • A ideia é calcular o valor dentro da precisão desejada pelo usuário
  • Ex.: ao representar π com erro de 0.01, retorna-se 3.14
  • Mas essa abordagem dificulta comparações exatas

O problema de representar o zero exato

  • Na abordagem RRA, 1 - 1 pode acabar sendo representado não como 0, mas como 0.0000000001
  • Isso gera um problema do ponto de vista da experiência do usuário (UX)
  • Boehm começou a buscar uma solução em colaboração com outros pesquisadores

O algoritmo de Richardson-Fitch

  • Em 1994, Dan Richardson e John Fitch resolveram o problema de comparação de números em certas operações
  • Mas o algoritmo é lento demais para uso prático
  • Por exemplo, para determinar 1 ≠ 1 - e^(-e^1000), seriam necessárias mais operações do que o número de átomos no universo

A combinação de RRA com operações racionais

  • Boehm teve a ideia de combinar as vantagens do RRA com as operações racionais
  • Em operações simples (ex.: 6 × 9 ou 8 / 3), usa-se aritmética racional
  • O RRA só é usado quando entram irracionais
  • Como resultado, os números passam a ser representados na forma racional × real

Representação simbólica (Symbolic Representation)

  • Números especiais como π e √2 usam representação simbólica em vez de RRA
  • Ex.: π é armazenado como o símbolo "π" e convertido em número apenas quando necessário
  • Além das quatro operações básicas, funções trigonométricas (sin, cos, tan), logaritmos e funções exponenciais também usam representação simbólica

A solução final

  • Todos os números são armazenados na forma racional × real (representação simbólica ou RRA)
  • Sempre que possível, usa-se aritmética racional para manter a exatidão
  • A representação simbólica é aproveitada ao máximo para minimizar operações RRA
  • Como resultado, foi criado um sistema de calculadora perfeito, equilibrando velocidade e precisão

Conclusão

  • A calculadora do Android criada por Boehm e sua equipe não é um programa simples
  • Ela aplica algoritmos rápidos e eficientes sem abrir mão de resultados exatos
  • Não é "só um app de calculadora", mas um sistema matematicamente sofisticado

"Da próxima vez que você usar a calculadora do Android, vale lembrar desse esforço!"

12 comentários

 
street62 2025-02-20

Como observação à parte, é interessante que a IA neo tenha traduzido como "é, né". O original é "Anyone could make that", então não tem esse tom brincalhão, haha, mas caiu como uma luva.

 
gurugio 2025-02-19

Quando eu era aluno de graduação, tive uma aula em que montávamos uma placa 8086 soldando tudo à mão, conectávamos um teclado numérico e um LCD de texto, e chegávamos a fazer uma calculadora (que só fazia as quatro operações) em assembly para 8086.
Consegui montar a placa e fazer o teclado e o LCD funcionarem, mas não consegui fazer a calculadora.
Na época, achei que não tinha talento para software e arrumei emprego como engenheiro de hardware, mas por acaso acabei trabalhando com desenvolvimento de software.
Calculadora é difícil mesmo.

 
yunsub2 2025-02-19

Não é geojana, e sim geojanha. 😃

 
carnoxen 2025-02-18

Aplicativo de calculadora? Qualquer um consegue fazer, né?

Mas ajustar ponto flutuante vai dar uma bela dor de cabeça, hein? kkkkk

 
tribela 2025-02-18

Quando falam em calculadora, eu logo penso na calculadora padrão do Windows. Se você calcular 2+2*2, o resultado sai 8, e não 6. Parece que fizeram isso de propósito, mas eu realmente não entendo. Lembro que uma vez calculei a quantidade de álcool em um coquetel e fiquei chocado porque deu mais álcool do que o volume total da bebida.

 
khrad 2025-02-19

Ele segue o funcionamento típico de uma calculadora eletrônica comum, em que a expressão anterior é calculada imediatamente toda vez que você pressiona um operador; será que você só usou calculadora científica?

 
ned0909 2025-02-18

Concordo totalmente. Comecei com uma calculadora achando ótimo não precisar de servidor, mas sofri demais para corrigir os erros de cálculo e os bugs que foram aparecendo.

 
aer0700 2025-02-17

"Um app de calculadora? Qualquer um consegue fazer isso" → na verdade, não é bem assim
Parece que isso tem aplicações praticamente infinitas kkk

"Python? É moleza total" → na verdade, não é bem assim

 
tsboard 2025-02-17

Eu também pensei a mesma coisa enquanto assistia. kkk

"JavaScript? Moleza total" → na verdade, não é bem assim

 
joyfui 2025-02-17

"(10^100)+1−(10^100)"
Nossa, de fato a calculadora do iPhone mostra 0, e a do Android mostra 1.
Mas, curiosamente, se pesquisar no Google, aparece 0...

 
GN⁺ 2025-02-17
Comentários do Hacker News
  • História interessante. Uma forma mais poderosa de representar números é com frações contínuas. Frações contínuas conseguem representar números reais e racionais de forma eficiente
    • Curiosidade: segundo um livro de matemática não tão antigo, acreditava-se que provavelmente não existiam algoritmos de adição/multiplicação para frações contínuas. Mas em 1972 Bill Gosper provou que frações contínuas são perfeitamente adequadas para aritmética
    • Estou trabalhando em uma biblioteca Python chamada reals. Ela foi projetada para substituir os tipos Decimal ou Fraction. Manipula frações contínuas usando as técnicas de Bill Gosper
  • É uma pena que o link tenha sido encurtado e não dê para clicar. Aqui está o link real para o artigo
  • Ri assim que li o título. IEEE 754 é horrível, mas ainda é melhor do que todas as alternativas. Assim que vi o exemplo, achei que seria sobre Kahan summation ou um sistema completo de álgebra computacional. Nunca tinha ouvido falar de Recursive Real Arithmetic
    • Ganhei uma perspectiva sobre um dos primeiros heróis do C++. Serve como lembrete de quão profundas podem ser as coisas que parecem simples
  • A tarifa do metrô de NYC é $2.90. Quando usei o PCalc no iOS para calcular o valor restante do meu MetroCard, o resultado foi -8.881784197E-16 em vez de 0. Isso não acontece ao usar a calculadora da Apple
    • Entrei em contato com o desenvolvedor, e ele respondeu que a Apple usa sua própria biblioteca matemática e que seria preciso encontrar outra biblioteca para substituí-la
  • Quase ninguém fez um aplicativo de calculadora realmente completo. Quero dizer uma calculadora completa como uma TI-89
    • Estou usando um emulador da calculadora TI-89 no Android. Ele não tem nem metade das funções de um app Android e não funciona bem
  • A desvantagem de mudar para RRA não é só a experiência do usuário. Quando o resultado é 0.0000000..., a calculadora não consegue decidir se pode calcular o inverso desse número
    • Por exemplo, 1/(atan(1/5)-atan(1/239)-pi/4) mostra "não é possível calcular". Se tentar 1/(atan(1/5)-atan(1/239)-pi/4+10^(-100000)), ainda assim mostra "não é possível calcular"
  • Quase nenhum número pode ser representado em ponto flutuante IEEE. A probabilidade de um número aleatório não poder ser descrito teoricamente pode ser de aproximadamente 100%
    • Alguns problemas podem ser evitados usando bignums. A crise existencial momentânea foi resolvida
  • Alguém sabe se calculadoras TI mais avançadas, como a TI-92, usavam esse sistema? Havia um modo de "racionais", então talvez usassem RRA
  • A forma de usar "recursive real arithmetic" (RRA) me lembrou uma excelente discussão com Conal Elliot. Era sobre sair de uma representação discreta das coisas para uma representação contínua
    • Por exemplo, antes as fontes eram representadas como blocos de pixels, mas agora são vistas como linhas/vetores. Ciência da computação deveria ser sobre buscar a verdade, não apenas aprender as ferramentas comerciais mais recentes
  • Brinquei com o código-fonte da calculadora do Android Open Source Project. O Google a moveu para o Google Play Services, mas o código antigo ainda está disponível
    • Resolve alguns problemas reais, e espero que possa ser usado em bibliotecas. Houve uma discussão sobre algumas bibliotecas no artigo anterior