Реализация калькулятора в мобильном приложении
Калькулятор выглядит тривиально — пока не нужно поддержать цепочки операций, обрабатывать потерю точности при операциях с плавающей точкой и не получить от 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 дня.







