Blog

Jak Boring Expenses przechowuje pieniądze (i dlaczego jako liczbę całkowitą)

  • inżynieria
  • iOS
  • Swift

Jest klasyczny sposób na zgubienie grosza. Zapytaj niemal dowolny język programowania, ile to 0.1 + 0.2, a odpowie 0.30000000000000004. To nie błąd języka — tak działają binarne liczby zmiennoprzecinkowe. Nie potrafią dokładnie zapisać większości ułamków dziesiętnych, więc wkradają się drobne błędy. W fizyce to nie problem; w pieniądzach — tak.

W aplikacji finansowej „mniej więcej dobrze” to zła odpowiedź. Dlatego Boring Expenses nigdy nie zapisuje kwoty jako liczby dziesiętnej.

Najmniejsza jednostka jako liczba całkowita

Sztuczka, której oprogramowanie finansowe używa od zawsze: liczyć w najmniejszej jednostce i trzymać ją jako liczbę całkowitą. Zamiast 4,20 zł zapisujesz 420 — liczbę groszy. Liczby całkowite są dokładne. Dodawaj, odejmuj i sumuj cały dzień, a nie nazbiera się żaden pył zaokrągleń.

Boring Expenses idzie o krok dalej i zapisuje kwoty w bardzo drobnych podjednostkach (pomyśl o „100 milionach na jednostkę”), co zostawia mnóstwo zapasu na różne waluty i przyszłe potrzeby, a jednocześnie wszystko pozostaje zwykłym Int. Przeliczenie na to, co widzisz na ekranie, odbywa się tylko na krawędziach — gdy wpisujesz kwotę i gdy formatujemy ją do wyświetlenia.

// Ilustracja, nie dokładny kod:
let display = Decimal(amountInSubunits) / Decimal(subunitsPerUnit)
let text = display.formatted(.currency(code: userCurrency))

Dlaczego to ma dla ciebie znaczenie

To mała, niepozorna decyzja — dokładnie taka, jakie lubimy. Nigdy jej nie zobaczysz i o to chodzi: liczby po prostu się zgadzają.