[JavaScript] 계산기

Naakite·2022년 2월 20일
0

📁토이프로젝트

목록 보기
3/5

벌써 자바스크립트에 입문한지 한달이라는 시간이 지났다..이번주는 수업도 따라가기 힘들어서 간단한 토이프로젝트를 하자는 생각에 계산기 만들기를 했는데, 예상과 달리 나의 실수들로 인해 꽤 긴 시간 생각하게 만든 토이프로젝트다.


📌 구현해야하는 기능들을 전체적으로 파악하지 못함.

이전에 만든 토이프로젝트들은 대략적으로 구현해야하는 기능들을 순서대로 적어놓고 시작하였는데, 이번에는 '계산기는 뭐 계산밖에 더 있나~' 하는 생각에 그냥 시작했다. 즉 구현해야하는 기능들을 전체적으로 파악하지 않은 상태에서 구현부터 시작했고 , 실수의 시작이였다.

잘못된 시작

btnAll.forEach(button => {
  button.addEventListener('click', (btn) => {
    switch(btn.target.className || btn.target.id){
      case "num": // 숫자
        ...
        display.innerText += btn.target.textContent;
        break;
      case "operator": // 연산자
        ...
        display.innerText += btn.target.textContent;
        break;
      case "clear": // 끝
        display.innerText = null;
        ...
        reset();
        break;
      case "end":
          Calculate_array();
          Calculate_result();
          input_display();
          break;
      case "num_decimal":
        display.innerText += btn.target.textContent;
          break;       
    }
  })
});
function Calculate_array(){
   for(let i=0; i<display.innerText.length; i++){
      array.push(display.innerText[i]);
   }
   return array;
}

내가 처음에 짠 코드들이다. 나는 일단 버튼을 입력하면, 예를들어 '5+5' 를 입력한다고 생각하면, display 화면에 5+5 를 출력하고 이것들을 하나의 배열로 만들었다.

그리고 나서 나는 숫자와 연산기호를 구분하기 위해, 만약 배열의 요소 숫자이거나 소수점이면 num_array 로 저장하고, 아니면 연산 기호로 저장하여, 저장된 연산 기호에 따라 계산을 하여 출력하는 과정으로 코드를 구성하였다. 이렇게..잘 마무리가 되는듯 했으나.....나는 놓쳐버린 것들을 발견한다...😭

✅ 마이너스 에러


...음수를 생각하지 않은 것이다.😲 스스로 생각해도 어이가 없었다..아무리 생각하기 쉬운 문제들이라고 해도, 구현하기 전에 다시 한번 스스로 순서를 적어보는 중요성을 깨닫게 되었다. 처음에는 음수를 해결하기 위해 인덱스가 0이면서 - 일 경우, 음수 값으로 넣어줬다.

 array.forEach((item, index) => {
    if (index == 0 && item == "-")
    {
      negative_num.push(item);
    }

이렇게 잘 해결하는 듯 했으나.. 이건 음수가 첫번째 숫자일때만 가능했고, 두번째 숫자가 음수일 경우에 대해서 인덱스 값을 어떻게 지정해야 할지에 대해 또 다시 생각해야 했다.
이 부분에 대해서는 또 다시 연산 기호에 원소가 있고, -일 경우로 구분하여 값을 넣어줬다.

   if(oper.length == 1 && item == "-") 

이렇게 발생하는 문제들은 해결했으나, 코드가 너무 길어졌다. 그리고 무엇보다, 마음에 들지 않았다...😭 가독성은 이미 없어졌고, if문들이 남발했다.😠
내가 토이프로젝트들을 하는 이유는 완성이 목적이 아니라, 자바스크립트를 배우기 위해서였는데, 어쩌다보니 그저 계산기를 완성하기 위해서 엉망인 코드를 구현해버린 것이다.

결국 처음부터 다시 구현을 시작했다! diplay에 입력 후 -> 배열로 push.
하는 방법 대신에 처음부터 num1, num2로 구분하여 구현을 하였다.
처음부터 구현하니, 불필요하게 배열들로 다시 push 해야하는 과정들은 생략되었고, if 문으로 다시 숫자인지 연산기호인지, 음수기호를 따로 구분하지 않아도 되었다.

✅ 부동 소수점 문제


이 문제는 첫번째로 구현했을 때와 다시 구현했을 때 똑같이 문제가 발생하였다. 0.2 * 7 을 계산했는데, 1.4가 아닌 1.400000000000001 으로 출력되는 문제가 발생했다. 이것 뿐만 아니라 실수 더하기들도 저런 문제가 발생했다.
처음에는 내 코드가 잘못되었다고 생각하여, 다시 살펴봤지만 문제가 될 부분이 보이지 않았고, 다시 코드들을 구현하였음에도 문제는 해결되지 않았다. 구글 검색을 통해 실수 계산시 대부분의 프로그래밍 언어가 겪고 있는 부동 소수점 문제라는 것을 알아냈다. 이때 해결 방법에는 대표적으로 toFixed()로 출력할 소수점을 지정하는 방법, Math.round() 을 이용해 반올림 하는 방법이 있었다.
하지만, toFixed 를 사용하면, 만약 toFixed(2)로 지정한다면, 0.02+0.03=0.06으로 소수점 문제가 해결되지만, 0.1+0.1 = 0.20으로 출력이 되었고, 0.032+0.052 = 0.084 이지만, 0.09로 출력되는 문제가 생겼다. 매번 계산해야하는 값들이 다른데 한가지로 지정할 수가 없는 것이다. 고민끝에 toFixed(5) 로 지정하였고, 0.1+0.1 = 0.20000 으로 출력하지 않도록, 뒤에 0을 생략하는 방법을 찾았다.

 calculate_result.push(parseFloat((num1 * num2).toFixed(5)));

해결방법으로 다시 실수처리를 하면, 소수점 뒤에 0들을 생략되었다.
이런 방법으로 부동 소수점 문제도 해결하였다!


🎯 완성


먼 길을 되돌아 완성하게 되었지만, 느끼고 반성한 부분들이 많았다.
다음부터는 꼭! 구현해야하는 기능들을 동작의 순서대로 생각해보고, 놓치는 부분이 있는지 다시 한번 더 생각하자!

profile
👩‍💻🏃‍♀️

0개의 댓글