0.1 + 0.2 === 0.3? | 부동소수점과 toFixed

없는블로그·2021년 9월 7일
0
post-thumbnail

😡 문제발생..

프로젝트 진행 중 생각지도 못했던 심각한 문제가 발생했다.

장바구니에 담은 음식의 칼로리를 소수점 단위로 조절하는 부분에서

이런 충격적인 일이 발생했다. 0.5,,, 0.4,,, 0.3....????


0.1 + 0.2 = ??

결론부터 말하자면 0.1 + 0.2 != 0.3 이라고 한다.


이유가 무엇일까?

Javascript에서는 부동소수점 방식으로 실수를 표현한다. 이게 무슨 말이냐면 정수가 아닌 실수를 나타낼 때 이진법을 사용하므로 모든 숫자를 정확히 나타낼 수 없고, 그 실수에 가장 근사한 2진법의 수로 나타내기 때문에 나타나는 문제이다.

이런 이유 때문에 위의 결과가 나오게 된다고 한다. 조금 더 기술적으로 접근한다면 이러한 이유가 있다고 한다. 단순하게 0.1이나 0.2, 0.3을 할당해준다면 문제가 없겠지만 각각의 수를 더할 때 발생하는 문제였다.

알고보니 알사람은 다 아는 기본적인 프로그래밍 언어의 문제라고 한다.....
https://0.30000000000000004.com/ 충격적이게도 이런 사이트도 존재했다...........
사이트를 들어가보면 해당 문제가 발생하는 언어를 정리해 놓았다.


어떻게 해결할까?

소수점의 자리수를 제한하는 toFixed() 함수를 사용했다.

  // 갯수 카운팅하기!
  const [count, setCount] = useState(props.amount);
  const upCount = () => {
    if (count >= 0.5) {
      setCount(count + 0.5);
      !editChk
        ? dispatch(setUpAmount(props.foodId))
        : dispatch(editUpAmount(props.foodId));
    } else {
      setCount((count + 0.1).toFixed(1));
      !editChk
        ? dispatch(setUpAmount(props.foodId))
        : dispatch(editUpAmount(props.foodId));
    }
  };

카운팅한 값을 .toFixed(1) 함수를 통해 카운팅 결과값을 소수 1째자리 까지만 제한하였다.


🤬 하지만 여기서 또 다른 문제의 발생!!!

바로
0.5 -> 0.4 -> 0.3 -> 0.2 -0.1 연산은 문제없이 계산되었는데

0.2 -> 0.2 +0.1 연산은 계산되지 않았다.

원인을 찾기위해 console을 찍어보니...

바로,, toFixed()String을 반환하는 함수 였다.


그렇다면 왜??? '-'연산은 되는데, '+'연산은 안될까?

원인은 자바스크립트에서 +-*와 달리 문자열을 연결해 붙이는 기능을 가지고 있기 때문이었다.


바로 이렇게 문자열이 섞인 연산에서 +- 와 다른 역할을 수행한다.


해결

  // 갯수 카운팅하기!
  const [count, setCount] = useState(props.amount);
  const upCount = () => {
    if (count >= 0.5) {
      setCount(count + 0.5);
      !editChk
        ? dispatch(setUpAmount(props.foodId))
        : dispatch(editUpAmount(props.foodId));
    } else {
      setCount(Number((count + 0.1).toFixed(1)));
      !editChk
        ? dispatch(setUpAmount(props.foodId))
        : dispatch(editUpAmount(props.foodId));
    }
  };

이렇게 toFixed()를 통해 반환된 String 결과값을 Number() 함수를 통해 숫자로 바꿔어주었다.


생각

  • 전혀 예상치 못한 문제였기 때문에 많이 당황했다.
  • 아직도 Javascript는 배울게 넘치고 넘치구나...를 느꼈다.
profile
없는블로그

0개의 댓글