Блог

Як Boring Expenses зберігає гроші (і чому цілим числом)

  • інженерія
  • iOS
  • Swift

Є класичний спосіб загубити копійку. Запитайте майже будь-яку мову програмування, скільки буде 0.1 + 0.2, і вона відповість 0.30000000000000004. Це не помилка мови — так працюють двійкові числа з рухомою комою. Більшість десяткових дробів вони не можуть зобразити точно, тож закрадаються крихітні похибки. Для фізики це нормально; для грошей — ні.

Для фінансового застосунку «приблизно правильно» — неправильна відповідь. Тому Boring Expenses ніколи не зберігає суму як десятковий дріб.

Найменша одиниця як ціле число

Прийом, яким фінансовий софт користується віддавна: рахувати в найменшій одиниці й тримати її як ціле число. Замість 4,20 ₴ ви зберігаєте 420 — кількість копійок. Цілі числа точні. Додавайте, віднімайте й підсумовуйте цілий день — і жодного пилу округлення не набереться.

Boring Expenses іде на крок далі й зберігає суми в дуже дрібних підодиницях (уявіть «100 мільйонів на одиницю»), що лишає чималий запас для різних валют і майбутніх потреб, а все при цьому залишається звичайним Int. Перетворення на те, що ви бачите на екрані, відбувається лише на краях — коли ви вводите суму і коли ми форматуємо її для показу.

// Ілюстрація, не точний код:
let display = Decimal(amountInSubunits) / Decimal(subunitsPerUnit)
let text = display.formatted(.currency(code: userCurrency))

Чому це важливо для вас

Це маленьке, непомітне рішення — саме такі ми любимо. Ви його ніколи не побачите, і в цьому суть: цифри просто сходяться.