V vitor.rocha
todos os projetos // projeto · c → webassembly

Calculadora em C

Todo o cérebro da calculadora é um único arquivo C sem biblioteca padrão, compilado direto para WebAssembly — o JavaScript apenas conecta os botões ao binário.

Banner do projeto Calculadora em C

Visão geral

Uma calculadora de aparência familiar escondendo um exercício de baixo nível: o motor inteiro — estado, operações, porcentagem, raiz quadrada e a conversão de número para texto — é C freestanding, sem libc, compilado para um binário WebAssembly de 12 KB que roda em qualquer navegador.

O problema

Sem biblioteca padrão, nada vem de graça: não há printf para formatar números, nem sqrt pronta, nem quem decida o que acontece quando alguém digita 5 + 3 × 2 e espera o comportamento clássico de calculadora. Cada regra precisou ser definida e implementada do zero.

A solução

O motor implementa uma máquina de estados no estilo das calculadoras clássicas (5 + 3 × 2 = 16), porcentagem contextual — em soma ela age sobre o acumulado (200 + 10% = 220), em multiplicação é fração (200 × 10% = 20) —, igual repetido, raiz por Newton-Raphson e um conversor próprio de double para texto com vírgula decimal pt-BR. A compilação usa clang com alvo wasm32, sem Emscripten, orquestrada por um Makefile com alvos de build, teste e servidor local.

Funcionalidades

  • Quatro operações com encadeamento no estilo calculadora clássica
  • Porcentagem contextual e igual repetido
  • Raiz quadrada por Newton-Raphson e unárias aninhadas
  • Formatação pt-BR feita à mão, com 15 dígitos significativos
  • Teclado físico com feedback visual nos botões
  • 23 casos de teste validando o motor via Node.js

Arquitetura

Três camadas bem separadas: calc.c é o motor puro e exporta funções; app.js só traduz cliques e teclas em chamadas ao binário e escreve o resultado na tela; o HTML e o CSS cuidam da aparência. O calc.wasm versionado permite que o GitHub Pages sirva o projeto direto da raiz, sem etapa de build no deploy.

Screenshots

Desafios & aprendizados

Os bugs mais instrutivos vieram da conversão numérica: potências de dez calculadas em laço sujavam o último dígito, resolvido com exponenciação binária; e a decisão de exibir 15 dígitos significativos — para 0,1 + 0,2 mostrar 0,3 — virou uma lição prática sobre ponto flutuante IEEE 754 e sobre escolher honestidade em vez de falsa precisão.