[목차]
- 서론
- 문제 현상 & 알아야 하는 이유- 원인 분석
- 컴퓨터가 이해하는 언어- 해결방안
- 2가지
[서론]
const num4 = 0.1 + 0.2;
console.log(num4); // 0.30000000000000004 출력
[원인 분석]
컴퓨터는 신호가 있을 때는 1, 없을 때는 0의 두가지로 모든 것을 표현한다. 따라서 인간이 입력한 10진법의 값을 본인들이 사용하는 2진법으로 바꾼 뒤 계산하게 되는데 이 때 첫번째 문제점이 발생한다.
"10진법의 유한소수를 2진법으로 바꾸면 무한소수가 나오는 경우가 있다."
ex)
0.1(10진법) -> 0.000110011001100...(2진법)
"컴퓨터의 저장공간은 유한하다"
컴퓨터는 숫자를 '표준 부동소수점'이라는 방식으로 저장한다.
표준 부동소수점 (=IEEE 754)
부동소수점
= 浮: 뜰 부, 動: 움직일 동
즉, 소수점의 위치를 옮겨서 숫자를 표현하는 방식
이 때 주로 32bit의 유한한 공간에 저장을 하게 되고, 위의 예시에 해당하는 0.1(10진법)은 아래와 같이 표현된다.
0.0001100110011 ...
1.100110011 ...
0 0111101 11001100 11001100 11001101
- --------- -
따라서 이렇게 오차가 생길 수 밖에 없게 되고, 제목의 상황처럼 10진법으로 계산했을 때는 깔끔하게 떨어져야할 값이 부정확해지는 것이다.
[해결방안]
실수 범위에서 계산할 때 나타나는 문제이므로 가급적 정수로 고쳐서 표현하자.
ex)
const num5 = (1 + 2)/10;
console.log(num5); // 0.3 출력
-> 위와 같이 각 숫자를 정수로 고친 뒤 계산을 하게되면 오류가 발생하는 것을 막을 수 있다.
float은 7자리, double은 15~16자리 까지 표현할 수 있습니다.
각 언어마다 제공하는 정확한 실수 계산을 위한 라이브러리들을 사용한다.
Java | JavaScript | Python |
---|---|---|
BigDecimal | big.js | decimal 모듈 |
-> 기본 자료형의 한계를 소프트웨어적으로 보완해준다.