본문 바로가기
Javascript

소수점 계산 시 정확한 계산 결과를 위한 적용 방법

by 즐코딩 2023. 2. 8.
반응형

소수점 계산 시 정확한 계산 결과를 위한 적용 방법

 

지난번 포스팅에서,  Javascript에서 소수점을 포함한 수를 계산할 때 나타날 수 있는 미세한 오차들의 원인에 대해서 살펴보았습니다.

 

0.1 + 0.2 = 0.3이 아니다? 소숫점 계산 시 주의 사항

 

0.1 + 0.2 = 0.3이 아니다? 소숫점 계산 시 주의 사항

0.1 + 0.2 = 0.3이 아니다? 코딩을 한창 재미있게 배우다가 어랏? 하게 되는 지점이 있습니다. 바로 '소숫점 계산'과 관련한 내용입니다. 일단 브라우저 console 창에 0.1 + 0.2를 실행해보시기 바랍니다.

kincoding.com

 

 

미세한 오차들에 의해서 발생할 수 있는 결과를 미연에 방지할 수 있는 몇 가지 기법들에 대해서 살펴보기로 합니다.

 

 

 

소수를 정수로 만들어 계산하는 방법

 

이전 포스팅에서도 살펴본 알고리즘인데요, 복습 차원에서 한번 더 살펴보기로 합니다. 아래와 같은 계산식을 사용하여 정수로 변환하여 계산을 하는 경우 소수점 연산에 의한 미세한 오차를 사전에 방지할 수 있습니다.

<script>
  const num1 = 0.1;
  const num2 = 0.2;

  function sum(num1, num2) {
    const newNum1 = num1 * 10;  //10을 곱해서 소숫점을 없애줌
    const newNum2 = num2 * 10;  //10을 곱해서 소숫점을 없애줌

    const result1 = newNum1 + newNum2;   // 10진수 상태로 덧셈 진행
    const result2 = result1 / 10;        // 처음 곱했던 10이 있으니 다시 10으로 나누어줌

    return result2;
  }
  
  console.log(sum(num1, num2));
</script>

 

 

 

미세한 오차를 무시하고 잘라내는 방법 - toFixed()

 

toFixed() 함수를 사용하여, 오동작할 수 있는 미세한 오차를 사전에 잘라내는 방법을 사용할 수 있겠습니다.

 

toFixed() 메서드는 숫자를 고정 소수점 표기법(fixed-point notation)으로 표시합니다.

 

다시 말해서, toFixed()는 Number 객체를 주어진 digits 만큼의 소수점 이하 자리수를 정확하게 갖는 문자열 표현으로 반환합니다. 소수점 이하가 길면 숫자를 반올림하고, 짧아서 부족할 경우 뒤를 0으로 채울 수 있습니다. 메서드를 호출한 숫자의 크기가 1e+21보다 크다면 Number.prototype.toString()을 호출하여 받은 지수 표기법 결과를 대신 반환합니다.

 

한편, 파라메터 자리에는 정수를 넣어서, 소수점 몇째 자리에서 Fix 할 것인지 자릿수를 결정할 수 있습니다.

const num1 = 0.1;
const num2 = 0.2;

function sum(num1, num2) {
  const result = (num1 + num2).toFixed(1);
  console.log(result, typeof result);
  return result;
}

console.log(sum(num1, num2));

콘솔-창에-출력했을-때&#44;-검정색-글자는-문자열(string)을-의미합니다.(숫자형은-파란색)
콘솔 창에 출력했을 때, 검정색 글자는 문자열(string)을 의미합니다.(숫자형은 파란색)

 

주의 - 문자열로 반환합니다!(숫자 자료형으로 반환하는 것이 아님에 주의 합니다!)

 

결과값이 문자열이기 때문에 그대로 두는 경우, 버그의 온상이 될 여지가 남습니다.

따라서, 계속 숫자 자료형으로 활용을 해야 하는 경우라면, number()를 이용해서 강제로 캐스팅해 주거나, parseFloat() 등을 사용해서 형변환을 시켜줄 수 있겠습니다.

 

위 예제에서는 다음과 같이 함수에서 return을 해줄 때 parseFloat()를 붙여줄 수는 방식으로 보완할 수 있습니다.

const num1 = 0.1;
const num2 = 0.2;

function sum(num1, num2) {
  const result = (num1 + num2).toFixed(1);
  return parseFloat(result);  //리턴하는 결과에 parseFloat()를 적용
}

console.log(sum(num1, num2), typeof sum(num1, num2));  //typeof를 찍어봅시다

string-&rarr;-number로-자료형이-변경되었습니다.
string &rarr; number로 자료형이 변경되었습니다.

 

 

number()와 parseFloat()의 차이점은 이전에 작성한 관련 포스팅을 참고해 주세요.

 

Number()와 parseInt() 차이점 - parseInt(string, radix)

 

Number()와 parseInt() 차이점 - parseInt(string, radix)

문자열을 숫자로 자료형 변환 하기 Javascript를 공부하며 코딩을 하다가 '어라? 비슷한 명령어가 있네? 같은 기능을 하는 건가? 분명히 차이점이 있을텐데?' 싶은 기능 두 가지가 눈에 띄었습니다.

kincoding.com

 

 

마치며

 

그 밖에 적절한 반올림 문법을 만들어서 사용할 수도 있겠습니다.

 

컴퓨터의 이와 같은 소수 계산방식은 1과 0 만을 기억하는 메모리의 특성에 기인하는 것인데요, 이러한 동작원리 특성을 잘 이해해 두는 것이 차후에 만나게 될 overflow 현상이나, NaN(Not a Number) 그리고 Infinity와 같은 개념들에 대한 이해도 쉽게 할 수 있게 되는 것입니다.

 

즐거운 코딩생활, 즐코딩.

KINcoding.

 

반응형

댓글