Blog

Como o Boring Expenses guarda dinheiro (e por que é um número inteiro)

  • engenharia
  • iOS
  • Swift

Existe um jeito clássico de perder um centavo. Pergunte a quase qualquer linguagem de programação quanto é 0.1 + 0.2 e ela vai responder 0.30000000000000004. Não é um bug da linguagem — é assim que os números binários de ponto flutuante funcionam. Eles não conseguem representar exatamente a maioria das frações decimais, então pequenos erros vão entrando. Tudo bem para física; para dinheiro, não.

Em um app de finanças, “quase certo” é a resposta errada. Por isso o Boring Expenses nunca guarda um valor como número decimal.

Guardar a menor unidade como número inteiro

O truque que os softwares de dinheiro usam desde sempre é trabalhar na menor unidade e mantê-la como inteiro. Em vez de R$ 4,20, você guarda 420 — o número de centavos. Inteiros são exatos. Some, subtraia e totalize o dia inteiro, e nunca vai acumular poeira de arredondamento.

O Boring Expenses vai um passo além e guarda os valores em subunidades bem finas (pense em “100 milhões por unidade”), o que deixa bastante folga para diferentes moedas e necessidades futuras, mantendo tudo como um simples Int. A conversão para o que você vê na tela só acontece nas pontas — quando você digita um valor e quando a gente formata para mostrar.

// Ilustração, não o código exato:
let display = Decimal(amountInSubunits) / Decimal(subunitsPerUnit)
let text = display.formatted(.currency(code: userCurrency))

Por que isso importa para você

É uma decisão pequena e sem brilho — exatamente do tipo que a gente gosta. Você nunca vai vê-la, e esse é o ponto: os números simplesmente batem.