Реалізація калькулятора в мобільній програмі
Калькулятор виглядає тривіально — поки не потрібно підтримати цепочки операцій, обробити втрату точності при операціях з плаваючою точкою та не отримати від QA баг «0.1 + 0.2 = 0.30000000000000004».
Логіка вичислень та точність
Найважливіше рішення — де рахувати. Вбудовані типи Double / Float дають IEEE 754 floating-point з відомими обмеженнями. Для фінансового калькулятора або бухгалтерської програми це неприйнятно.
На iOS правильний шлях — NSDecimalNumber або Decimal з Foundation. Decimal(string: "0.1") + Decimal(string: "0.2") дає рівно 0.3. Для складних виразів — NSExpression або кастомний парсер з токенізатором. На Android — java.math.BigDecimal з явним указанням MathContext.DECIMAL128 та RoundingMode.HALF_UP при діленні. Ділити BigDecimal без MathContext — ArithmeticException при нетерміннуючому десятковому результаті (наприклад, 1/3).
Для парсингу виразів вигляду 2 + 3 * 4 з приоритетом операторів — алгоритм сортувальної станції (shunting-yard) Дейкстри. Реалізується за ~100 рядків, не потребує сторонніх залежностей, покривається unit-тестами на кожний edge case. Альтернатива — бібліотека exp4j на Android або MathParser.org-mXparser для крос-платформи.
UI та стан
Архітектурно калькулятор — скінченний автомат. Стани: idle, enteringFirstOperand, operatorEntered, enteringSecondOperand, resultDisplayed, error. Переходи між станами при кожному натисканні кнопки. Зберігати просто currentInput: String та operator: String — шлях до багів при серії натискання оператора підряд або натисканні = без другого операнду.
На iOS — ViewModel з @Published властивостями або Combine. На Android — ViewModel + StateFlow. У Flutter — BLoC або ChangeNotifier. Логіка вичисленнь — в окремому use case / сервісі, покриту тестами без залежності від UI.
Клавіатура: LazyVGrid в SwiftUI або GridLayout в Compose найпростіше. Єдиний нюанс — кнопка 0 зазвичай займає подвійну ширину, що потребує GridItem з span або окремого HStack для останнього рядка.
Типичні edge cases
- Ввід кількох точок в одному числі — потрібна перевірка перед додаванням символу
- Ділення на ноль — не краш, а відображення «Помилка» з можливістю почати заново
- Переповнення при дуже великих числах —
DecimalтаBigDecimalне переповняються якDouble, але результат може стати нечитаємим; потрібне обмеження на кількість цифр на дисплеї - Цепочка операторів:
5 + 3 * 2— рахувати зліва направо (як у простих калькуляторах) або з приоритетом множення? Залежить від ТЗ
Термін: базовий калькулятор з чотирма діями — 1 день. Науковий з приоритетом операторів, історією вичислень та BigDecimal — 2–3 дні.







