Блог
Як Boring Expenses зберігає гроші (і чому цілим числом)
Є класичний спосіб загубити копійку. Запитайте майже будь-яку мову програмування, скільки буде 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))
Чому це важливо для вас
- Підсумки точні. Сума за місяць — справжня сума, а не число, що зсувається на копійку зі зростанням списку.
- Синхронізація узгоджена. Ціле число означає те саме на iPhone, Watch та iPad. Немає нічого неоднозначного, що треба звіряти.
- Експорт надійний. Експортований CSV збігається із застосунком до копійки.
Це маленьке, непомітне рішення — саме такі ми любимо. Ви його ніколи не побачите, і в цьому суть: цифри просто сходяться.