이번엔 공학용 계산기를 구현해보겠습니다.
다음의 풀리퀘스트를 통해 최종적으로 메인에 적용되었으며 해당 링크를 통해 기록 조회가 가능합니다.
본 포스팅부턴 단순 공학용이 아니라, 메인을 수정하거나, 또는 별도의 DB를 생성하는 등 추가적인 작성이 다수 존재하여 가독성을 위해 커밋 단위 내용만 해설하고 별도 코드는 해당 링크를 통해 참고 바랍니다.
https://github.com/zeka0228/calculator/pull/3
[REFACTOR] 기능 추가에 따른 디렉토리 구분
main 파일에 모든 로직이 몰아서 존재했는데, 이제 본격적으로 타 모드를 구현하게 되니, 각각의 기능들을 나누어 구현해야합니다. 따라서 기본 계산기와 공학 계산기 디렉토리를 별도 생성하고, 동일하게 적용되는 수학 함수, 로직들은 완전히 분리하여 별도로 적용시킬 수 있도록 구분시키는 기초 작업을 선제적으로 진행했습니다. 추후 원하는 모드를 동작시키고자 할 경우 해당 모드의 Stateful 위젯만 호출하면 되도록 최적화가 진행됐습니다.
[REFACTOR] UI 및 연산 버그 수정
연산자 입력 후의 모드 변경 시 및 기타 출력 관련 버그의 수정을 진행했습니다. 기본 계산기에서 따로 식별하지 못했는데 관련 공학계산이 보다 많은 기능이 추가되어, 관련 내용에서 꼬인 부분이 존재했던 듯 합니다.
[REFACTOR] UI 수정 및 함수 구성 통일화
공학용 계산기의 전체 UI를 최종적으로 IOS 계산기와 유사하게 정리하는 마무리 작업과, 이들의 동작 함수 구성을 수정했습니다. 특히 함수의 경우 모든 기능은 _onButtonPressed()로 처리되나, 이들 토큰의 분류를 진행하고 처리함수를 호출하는 방식으로 구축하여 추후 분기점으로 인해 발생할 문제를 최소화하기 위해 구별 처리했습니다.
[FEATURE] 소괄호 및 mr 계열 로직 기초 구현
본격적으로 공학용 계산기 기능을 구현했습니다. 가장먼저 메모리 계열 기능인 mc m+ m- mr 기능의 기초적인 저장과 출력, 삭제 기능을 구현하였고, 소괄호를 각각 단독으로 입력할 수 있도록 설정하였습니다. 해당 메모리 계열 기능은 double? _memory에 저장되며 각각의 기능들을 통해 호출 또는 삭제할 수 있습니다.
[REFACTOR] mr 정책 구체화
mr의 기초 구현 중, 기능 구현을 우선적으로 진행하여 동작 방식 자체가 단순히 문자열로 삽입되는 형식으로 이루어졌습니다. 이 경우 메모리 값의 정책과 충돌하여 과거 mr 값이 유지되는 버그를 확인했고, 타 기능을 시작하기 전 이 부분을 수정하여 구체화 했습니다. mr을 토큰으로 보관하는 방식으로, 과거의 값이 유지되지 않도록 현재의 _memory 값을 룩업 처리할 수 있도록 수정했습니다.
[FEATURE] 지수 기능 구현 및 오버플로 에러 구분
지수 기능들의 연산 입력에 대해 실제 IOS의 계산기와 동일한 UI 출력이 이루어질 수 있도록 수정 및 인자가 완전히 입력되지 않은, 즉 두개의 변수를 받아야 하는 기능은 이에 대해 대기가 가능하도록 구축했습니다. 또한 NaN은 추후 정의되지 않음으로 분류되어야 할 필요가 있어, 우선 double 형을 벗어났을 때만 error로 이루어지도록 isInfinite를 구분했습니다.
[REFACTOR] 지수 기능 구체화 및 위첨자 표기화, 함수 동작 통일 실패로 발생한 버그 수정
기능 구현을 우선적으로 진행하여 당시 지수 표현은 ^ 을 이용하여 코딩하는 제 입장에서 당장 별도 입력이 필요 없이, 빠르게 진행할 수 있도록 위와 같은 표현을 임시로 채택했습니다. 전반적인 구현이 진행되기 시작했기 때문에 이 부분도 제대로 위첨자로 반영될 수 있도록 해당 표기를 구체화 했습니다. 다만 임의 수정이 존재했기에 일부 통일성이 훼손되어 해당 부분을 복구했습니다.
[FEATURE] 분수 구현 및 아이폰 계산기와 표기 동일화
전반적으로 IOS의 계산기와 동일한 출력으로 수정했습니다. 예를들어 1/x 기능은 실제로는 분수로 출력되도록 전반적인 표기를 IOS에 맞추는 디자인 수정을 진행했습니다.
[FEATURE] 다중 루트 파싱 오류 수정 및 구체화
루트 함수 등을 여러겹으로 생성 시, 파싱이 깨지는, 특히 인자값의 입력이 불가해지는 심각한 버그가 발생했습니다. 내부 구현 상 문제였는데, 단순히 다중 루트 또는 다중 공학 연산 시, 이를 그냥 일반적인 수학 연산의 중첩으로 치환하여 적용시키는 방식으로 구현했는데, 이 중첩이 결국, 제곱근을 예시로 들면 sqrt(()) 와 같이 잘못 매치되어 에러가 발생해 연산을 이이상 진행할 수 없는 오류였습니다. 이를 단순히 공학연산 함수로 이어지도록 매핑하는 것이 아니라, 식 자체의 Depth를 따, 이를 가능한 식으로 전개하여 그 식을 매핑하여 전개하는 방식으로 구현했습니다. 예를 들어 이중 제곱근이었다면 제곱근에 ^ (1/n) 과 같이 식을 변형하여 적용시키게 되면 위와 같은 오류를 차단할 수 있게됩니다.
[FEATURE] nroot 기능 구현 완료 / [FEATURE] ln() 기능 구현 완료
제곱근과 로그 기능을 구현했습니다. 사실 math에 존재하는 pow나 log를 적용시키면 되는거라 크게 뭐가 있는 작업은 아니었습니다. 다만 이들 모두 NaN이 존재하는 영역이라 이 부분만 분기처리했습니다.
[FEATURE] NaN 발생 시 출력 내용 변경
정의되지 않음 문제 발생시 이부분은 따로 출력되도록, 따라서 IOS와 동일하게 처리되도록 분기처리 및 출력 내용을 정의되지 않음으로 출력값을 변경했습니다.
[FEATURE] log10 기능 구현
똑같이 math를 이용해 log(10)으로 상용로그를 구현했습니다. 스포일러로 2nd 모드에 대비해야 했기에(log(x)) 내부를 _calcLog(double, double)로 미리 최적화 시켜뒀습니다.
[REFACTOR] 사칙연산 / 공학 연산 = 반복 기능 구분
공학연산에서 단항 함수로 동작하는 경우, 동일 적용시 오류가 나거나 예상치 못한 분기로 생성되는 문제가 식별되었습니다. 확인해보니 애시당초 IOS에서도 단항함수의 반복연산은 막아둔 것을 확인했습니다. 마음 편히, LastOperator를 통해 단항함수로 식별되는 경우에는 반복연산이 시행되지 않도록 명시적으로 제한시켰습니다.
[FEATURE] sin/cos/tan 및 sinh/cosh/tanh 구현 완료 및 연산식 리펙토링
삼각함수와 쌍곡함수를 math를 이용해 구현했습니다. 쌍곡함수의 경우 (e^x - e^(-x)) / 2 식을 명시적으로 입력하여 직접 구현했습니다. 찾아봐도 math에는 존재하지 않는 듯 했습니다. 또한 함수 분기가 과도하게 많아지는 우려가 생겨, 단항함수를 별도 헬퍼 함수로 분리시키는 과정을 함께 진행했습니다.
[REFACTOR] EE 표기 및 동작 제한 설정
직접 지수 표기법 모드를 구현했습니다. 다만 선제 조건으로 e가 미존재해야 함을, 그리고 마지막 토큰이 숫자여야 함을 명시했습니다.
[FEATURE] 2nd 기능 구현 완료
2nd 모드의 음수지수 삼각함수나 e^x, 로그나 2의 거듭제곱 등을 모두 구현했습니다. 구현되는 내용이 많아 분기점으로 형성하기엔 다소 어지러울 소요가 있어, Map을 통해 별도 매핑테이블로, 2중으로 구축하여 조회할 수 있도록 설정했습니다.
[REFACTOR] 다중 logy 버그 수정
logy를 다중으로 입력했을 때 파싱 자체에서 기존의 중복 루트와 동일한 패턴으로 잘못 입력되는 버그가 발생했습니다. 해당 부분을 통해 당시 중복 연산 시 오류가 중복 제곱근 뿐만이 아니라 중복 공학연산이( 그리고 소괄호가 포함되는) 존재하는 연산 모두에 적용될 위험이 있음을 확인하였고, 우선 당시와 동일한 방법으로 해결했습니다.
[REFACTOR] 정의되지 않음 상태 시 연산 불가되도록 수정
기능에만 집중하다보니 NaN인데도 연산이 작용되는 웃지 못할 버그가 존재했고 이를 식별하지 못하고 있었습니다. 마지막에 식별하여 이 NaN 결과값 자체를 bool연산자로 추가로 설정해 플래그로 써, 참일경우 오직 전체 초기화만 기능할 수 있도록 제한 기능을 설정했습니다.
이를 끝으로 공학용 계산기의 구축이 완료되어 master에 최종적으로 머지시켰습니다. 다음으로는 수학 메모를 구현합니다.
'Flutter > 과제 1차 : 계산기 만들기' 카테고리의 다른 글
| [FLUTTER 과제] 계산기 만들기(4) : 기록과 변환기 (0) | 2026.04.27 |
|---|---|
| [FLUTTER 과제] 계산기 만들기(3) : 수학 메모 (0) | 2026.04.27 |
| [FLUTTER 과제] 계산기 만들기(5) : 프로젝트 완성 시연 영상 (1) | 2026.04.26 |
| [FLUTTER 과제] 계산기 만들기(1) : 기본 계산기 (0) | 2026.04.17 |