Реализация калькулятора в мобильном приложении
Калькулятор выглядит тривиально — пока не нужно поддержать цепочки операций, обрабатывать потерю точности при операциях с плавающей точкой и не получить от QA баг «0.1 + 0.2 = 0.30000000000000004». Мы разрабатываем кастомные калькуляторы под ключ, гарантируя точность вычислений и надёжную архитектуру. Наш опыт — более 6 лет в мобильной разработке, свыше 30 проектов с кастомной логикой расчётов. Свяжитесь с нами для консультации — разберём ваш use case.
Почему точность вычислений критична для мобильного калькулятора?
Самое важное решение — где считать. Встроенные типы 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 для кросс-платформы.
Как архитектура конечного автомата упрощает разработку?
Архитектурно калькулятор — конечный автомат. Состояния: idle, enteringFirstOperand, operatorEntered, enteringSecondOperand, resultDisplayed, error. Переходы между состояниями при каждом нажатии кнопки. Хранить просто currentInput: String и operator: String — путь к багам при серии нажатий оператора подряд или нажатии = без второго операнда. На iOS — ViewModel с @Published свойствами или Combine. На Android — ViewModel + StateFlow. В Flutter — BLoC или ChangeNotifier. Логика вычислений — в отдельном use case / сервисе, покрытом тестами без зависимости от UI. Архитектура на SwiftUI и Combine обеспечивает реактивное обновление UI без лишних ререндеров.
Клавиатура: LazyVGrid в SwiftUI или GridLayout в Compose проще всего. Единственный нюанс — кнопка 0 обычно занимает двойную ширину, что требует GridItem с span или отдельного HStack для последней строки.
Что даёт использование BigDecimal и Decimal на практике?
Представьте приложение для расчёта процентов по кредиту. Если очередной платёж вычисляется через Double, накапливается ошибка порядка 0.01 за месяц. За год — уже 0.12, а за 10 лет — 12. Для банков это недопустимо. Использование Decimal/BigDecimal даёт копеечную точность на всём сроке, и баланс сходится с учётной системой банка.
Типичные edge cases и их решения
| Проблема | Решение |
|---|---|
| Несколько точек в числе | Проверять перед добавлением символа . |
| Деление на ноль | Отобразить «Ошибка», дать начать заново |
| Переполнение отображения | Ограничить количество цифр (например, 12) |
Цепочка операторов (5 + 3 * 2) |
Слева направо или с приоритетом — зависит от ТЗ |
Потеря точности при 0.1 + 0.2 |
Использовать Decimal / BigDecimal |
Почему стоит заказать разработку у нас?
- Более 6 лет опыта в iOS/Android/Flutter.
- Свыше 30 успешных проектов с кастомной логикой.
- Гарантия точности (0.1+0.2 = 0.3).
- Сертификаты Apple Developer и Google Play.
- Индивидуальный подход — свяжитесь, оценим ваш проект бесплатно.
Процесс работы над кастомным калькулятором
- Аналитика — согласуем математические операции, приоритеты, обработку ошибок, UI/UX.
- Проектирование — конечный автомат, ViewModel, тесты на краевые случаи.
- Реализация — парсер, точные вычисления, клавиатура, SwiftUI/Compose.
- Тестирование — unit-тесты, UI-тесты, проверка с плавающей точкой.
- Деплой — App Store Connect / Google Play Console, TestFlight, Firebase Distribution.
Сроки: базовый калькулятор с четырьмя действиями — от 1 дня. Научный с приоритетом операторов, историей и BigDecimal — от 2 до 3 дней.
Что входит в работу
- Исходный код с комментариями.
- Набор unit-тестов (покрытие >90%).
- Документация по состояниям и переходам.
- Доступ к репозиторию (GitHub/GitLab).
- Интеграция с CI/CD (опционально).
- Поддержка после деплоя (2 недели).
Сравнение библиотек для парсинга выражений
| Критерий | Собственный shunting-yard | exp4j (Android) | mXparser (кросс-платформа) |
|---|---|---|---|
| Размер | ~100 строк | ~200 КБ | ~1 МБ |
| Зависимости | Нет | Нет | Нет |
| Расширяемость | Полная | Ограниченная | Средняя |
| Поддержка скобок | Да | Да | Да |
| Точность | IEEE 754 / BigDecimal | Double | Double / BigDecimal |
Собственный парсер лучше подходит для простых калькуляторов — он быстрее и не добавляет лишних зависимостей. Для научных с функциями вроде sin/cos — mXparser или exp4j.
Получите консультацию по архитектуре вашего калькулятора. Пишите — разберём все edge cases вместе.







