부제 : 브라우저 콘솔창에서 console.log(0.1 + 0.2);
를 입력했을 때의 출력이 0.3이 아닌 이유
console.log(0.1 + 0.2);
// 0.30000000000000004
console.log(0.1 + 0.2 === 0.3);
// false
위와 같은 출력이 나오는 이유는 아래의 문장과 연관있다.
JavaScript Number 타입은 Java 혹은 C#의 double 타입처럼 IEEE 754 64비트 바이너리 배정 밀도 값입니다.
출처 : MDN - Number
컴퓨터의 메모리는 이진수 체계를 기반으로 데이터를 저장한다. 컴퓨터에서 실수를 표현하는 방식으로는 고정 소수점 방식(Fixed-Point)과 부동 소수점 방식(Floating-Point)가 존재한다.
소수점을 사용하여 고정된 자리의 소수를 나타내는 것이다. 한정된 메모리에서 부동소수점 방식보다 좁은 범위의 수만 나타낼 수 있다.
소수부의 자릿수를 미리 정하고 고정된 자릿수의 소수를 표현하기 때문에 직관적이다.
직관적으로 메모리에 실수 표현을 할 수 있다는 장점이 있지만, 표현 가능한 범위가 적다는 단점이 있다. 정수부가 큰 실수, 소수부가 큰 실수에 따라 공간 낭비가 발생하기도 한다.
부동소수점(浮動小數點, floating point) 또는 떠돌이 소수점[1] 방식은 실수를 컴퓨터상에서 근사하여 표현할 때 소수점의 위치를 고정하지 않고 그 위치를 나타내는 수를 따로 적는 것으로, 유효숫자를 나타내는 가수(假數)와 소수점의 위치를 풀이하는 지수(指數)로 나누어 표현한다.
출처 : 부동 소수점 - 위키백과
공간 낭비를 줄이고 효율적으로 실수 메모리를 표현하기 위해 컴퓨터는 부동 소수점 방식을 사용한다.
IEEE 754는 IEEE에서 개발한 컴퓨터에서 부동소수점을 표현하는 가장 널리 쓰이는 표준이다. 이 표준은 다음과 같은 형식을 정의한다.
단정밀도(single-precision)
배정밀도(double-precision)
십진수 9.625를 부동 소수점 이진법으로 변환하는 과정
9.625
를 이진수로 변환한다. 이 과정은 정수 부분과 소수 부분으로 나누어 처리한다. 1001.101
1.001101 * 2^3
x.yzabc..
의 형태를 띄는데 x의 범위는 반드시 1이 된다. 정규화 첫 번째 과정에서 이진수로 변환하기에 가장 높은 자릿수에 0이 올 경우는 존재하지 않는다. 그렇기에 yzabc..
부분을 가수부에 넣어 표현한다.0.1 + 0.2
가 3이 아닌 이유는 컴퓨터에서 실수를 표현할 때 부정소수점 형식을 사용하고 있기 때문이다. (JS에만 한정된 현상은 아니다.)https://www.youtube.com/watch?v=ZQDsWySjY6g
https://unagi-zoso.tistory.com/8
좋은 글 잘 봤습니다