Leo의 기술 블로그

부동 소수점 처리 본문

Frontend(Web, App)/JavaScript

부동 소수점 처리

LeoEngineer 2025. 7. 12. 15:07

고민 배경

 

어드민 페이지 개발중 서버로부터 받은 소수점 데이터에 100을 곱해 화면에 보여줘야하는 상황이 있었다. 

console.log(0.5295 * 100); // 52.949999999999996

 

내가 의도한건 52.95까지의 데이터가 나왔으면 했는데 실제로 화면에 표시되는건 의도하지 않은 데이터가 나왔다 이번 글은 이렇게 나온 이유에 대해서 컴퓨터가 어떻게 소수점을 표현하고 있는지도 같이 정리해보려고 한다. 

 

부동소수점 방식

 

컴퓨터는 값을 2진수로 표현할 수밖에 없다. 왜냐하면 미세하게 작은 트랜지스터의 집합으로 이루어져 있는데 이 트랜지스터의 켜짐과 꺼짐에 따라 값을 표현하고 있기 때문이다. 

즉 소수점도 2진수로 표현해야한다. 

 

앞에서 사용한 0.5295 값은 10진수의 값이다 이를 컴퓨터는 이해하지 못한다. 즉 컴퓨터는 이 값을 2진수로 변환해서 연산을 진행해야한다.

0.5295를 2진수를 변환하면 0.5295100.10000111100011010100111112​... 이런식으로 끝나지 않는 무한의 값으로 나온다.

 

해당 2진수의 값에 100을 곱하는 연산을 진행하고 나서 다시 10진수로 변한을 하니 52.949999999999996 이런식으로 값이 도출되었다.

즉 2진수로 정확히 표현하지  못하는 무한의 값을 가지고 연산을 진행하니 연산 결과인 무한대의 값을 메모리 제한에 맞게 제한해서 자른후 이를 다시 10진수로 변환했다고 볼 수 있다.

 

그럼 항상 소수점 연산의 결과는 52.949999999 처럼 무한의 값일까?

대답은 아니다.
console.log(0.625 * 2); // 1.25

 

 

위에 코드를 보면 소수점의 곱셈이여도 1.25까지 도출되는걸 볼 수 있다. 이 이유는 0.625는 2진수로 딱 나누어떨어지기 때문이다. 이 결과는 덧셈 뺄셈 곱셈 나눗셈 모두 동일하게 소수점이 2진수로 정확히 표현이 된다면 오차없는 정확한 값을 도출해낸다.

 

부동소수점 처리

function formatSettlementAmount(amount: number): number {
    const fixedString = (amount * 100).toFixed(2);
    return parseFloat(fixedString);
}

 

방법은 간단하다. 우리는 소수점이 있는 경우 셋째 자리에서 반올림값으로 보이도록 기획을 전달받았으니 toFixed 메서드를 이용해서 반올림 해주면 된다.

만일 소수점이 아닌 정수값을 받아올때는 52.00 이런식으로 나오기 때문에 뒤에 .00을 없애주기 위해 parseFloat 메서드를 사용해 어드민에 나오도록 수정하면된다.