JavaScript의 소수점 오차 생기는 이유

2025. 4. 6. 16:09·⭐FE

✅배경

프론트엔드 개발을 하다 아래와 같은 경우를 볼 수 있다.

분명히 0.1+0.2는 0.3이어야 되는데 0.3000000... 4 인 이유가 뭘까? 

그 이유는 자바스크립트는 IEEE754 64비트 `부동소수점` 방식으로  저장 되기 때문이다

💡자바스크립트의 숫자 표현방식

자바스크립트에서 모든 숫자는 내부적으로 IEEE754 64비트 부동소수점 방식으로 저장된다. 이 방식은 어떤 수를 저장하기 위해 64비트를 쓰며 항상 수를  1.??? * 2^n 형태로 인식하고 ???는 가수부, n부분은 지수부로 보고 각각 11비트, 52비트를 이용하여 표현한다. 추가로 1비트는 양수/음수를 구분하기 위해 사용한다.

  • 부호부: 1비트 사용, 양수/음수 구분 (0:양수, 1:음수)
  • 지수부: 11비트 사용, 2의 거듭제곱을 표현 ( 실제 계산 시 bias: 1023을 뺌)
  • 가수부: 52비트 사용, 유효 숫자.  `1.xxx` 형태의 `xxx`만 저장

하단은 몇가지 10진수가 IEEE754 64비트에 어떻게 담기는지 보여준다.

🤔왜 오차가 생길까?

10진수 `0.1`, `0.2`, `0.3`은 사람에겐 간단하지만 2진수로 정확히 표현할 수 없다. 

예를들어서 0.1과 0.2는 2진수로 표현하면 아래와 같이 무한소수가 된다

0.1 -> 0.0001100110011....(무한반복)
0.2 -> 0.00110011001100....(무한반복)

컴퓨터는 무한한 비트를 저장할 수 없기 때문에 중간에서 잘라서 반올림하고 이 과정에서 아주 미세한 오차가 발생하고 그결과 아래와 같은 현상이 발생한다. 이 반올림 되는 방식에 대해 궁금하면 round to nearest even 에 대해 알아보자

0.1 + 0.2 === 0.30000000000000004 // 실질적인 결과
0.1 + 0.2 === 0.3 // false 임

➕(참고)10진수 정수를 2진수로 바꾸는 방법

10진수 정수를 2진수로 바꾸는 방법은 간단하다. 몫이 0 이 나올때 까지 계속 2로 나눈 뒤 이제 각 단계에서 나온 나머지값을 역순으로 읽으면 된다. 아래에서 10진수 수 20을 2진수로 표현한 결과 10100 임을 확인 할 수 있다.

➕(참고)10진수 소수를 2진수로 바꾸는 방법

10진수 소수를 2진수로 바꾸는 방법은 소수부분이 0이 될 때까지 2를 곱한 뒤 각 단계에서 발생하는 정수부분의 수를 순서대로 읽으면 된다. 아래에서 0.5는 2진수로 0.1, 0.25는 0.01, 0.1은 0.00011001100110011 ... 임을 알 수 있다.

참고

https://en.wikipedia.org/wiki/Double-precision_floating-point_format

 

Double-precision floating-point format - Wikipedia

From Wikipedia, the free encyclopedia 64-bit computer number format Double-precision floating-point format (sometimes called FP64 or float64) is a floating-point number format, usually occupying 64 bits in computer memory; it represents a wide range of num

en.wikipedia.org

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Number

 

Number - JavaScript | MDN

Number 는 37이나 -9.25와 같은 숫자를 표현하고 다룰 때 사용하는 원시 래퍼 객체입니다.

developer.mozilla.org

 

 

 

 

'⭐FE' 카테고리의 다른 글

웹 서비스 캐시 다루기  (0) 2025.05.02
JWT ( Json Web Token )  (0) 2025.04.07
Event bubbling(버블링), Event Capturing(캡처링)  (0) 2025.04.03
이미지 포맷 형식 ( JPG, JPEG, PNG, WEBP )  (0) 2025.03.30
LRU ( Least Recently Used ) 알고리즘 구현해보기  (0) 2025.03.29
'⭐FE' 카테고리의 다른 글
  • 웹 서비스 캐시 다루기
  • JWT ( Json Web Token )
  • Event bubbling(버블링), Event Capturing(캡처링)
  • 이미지 포맷 형식 ( JPG, JPEG, PNG, WEBP )
devWarrior
devWarrior
  • devWarrior
    devWarrior
    devWarrior
  • 전체
    오늘
    어제
    • 🧩Dev (263)
      • ⭐FE (34)
      • 🔒Algorithm (155)
      • ➕Etc. (11)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Algorithm
    실버1
    오블완
    자바스크립트
    그리디
    구현
    실버2
    js
    백준
    Lv2
    react
    코딩테스트
    DFS
    node.js
    dp
    BFS
    프로그래머스
    Easy
    티스토리챌린지
    골드5
    알고리즘
    코테
    실버4
    프론트엔드
    javascript
    FE
    자스
    leetcode
    실버3
    nodejs
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
devWarrior
JavaScript의 소수점 오차 생기는 이유
상단으로

티스토리툴바