자바스크립트에는 이런 문제가 있다.
0.1 + 0.2 === 0.3 // false
0.1 + 0.2 // 0.30000000000000004
이유로는 자바스크립트 숫자 타입의 값이 IEEE 754의 부동소수점 표현 형식 중 배정밀도 64비트 부동소수점 형식을 따르고 모든 수를 실수로 처리하기 때문에 하나의 숫자 타입만 존재한다. 하나하나 천천히 살펴보자
IEEE 754
IEEE(Institue of Electrical and Electronics Engineer)에서 개발한 컴퓨터에서 부동소수점을 표현하는 방법을 정의한 것이며 널리 쓰이는 표준이다. 부동소수점을 표현하는 형식의 종류로는 2진법 부동소수점 형식과 10진법 부동소수점 형식이 존재한다.
이름 | 비트 수 | 지수 비트 | 가수 비트 | 지수 편향 |
binary16(반정밀도) | 16 | 5 | 10 | 15 |
binary32(단정밀도) | 32 | 8 | 23 | 127 |
binary64(배정밀도) | 64 | 11 | 52 | 1023 |
binary128(사배정밀도) | 128 | 15 | 112 | 16383 |
decimal32 | 32 | 7 | 23 | 96 |
decimal64 | 64 | 9 | 53 | 384 |
decimal128 | 128 | 13 | 126 | 6144 |
여기서 binary가 2진법을 뜻하며 decimal이 10진법 binary와 decimal 뒤에 나오는 숫자가 비트임을 의미한다.
배정밀도 64비트 부동소수점 형식
자바스크립트 숫자 타입의 값이 배정밀도 64비트 부동소수점 형식을 따른다고 했는데 부동소수점은 부호 부분, 지수 부분, 가수 부분이 존재한다.
- 부호 부분: 1bit로 양수이면 0, 음수이면 1이 된다.
- 지수 부분: 11bit로 아래 설명을 함께 살펴보자.
0.1을 2진법으로 변환해보자.
0.00011~에서 0011이 반복되는 순환 소수가 나오고 여기서 소수점의 자리를 1.~가 되도록 왼쪽 혹은 오른쪽으로 옮기고 0.00011~에서는 왼쪽으로 4칸 이동해야 1이 나오기에 1.11001100~X 2^-4와 같다. 여기서 지수 부분을 구하려면 2^-4의 지수인 4에다가 지수 편향을 더하고 2진법으로 변환해야 한다. 여기서 지수 편향은 양수를 2진법으로 표현할 수 있지만 음수를 2진법으로 표현할 수 없기에 지수 편향을 더한 다음 2진법으로 변환한다. 지수 편향 계산식은 2^(지수 부분의 총 비트 수 -1) -1이고, 64비트의 지수 부분은 11bit니까 2^(11 - 1) - 1 = 1023이다. 따라서, 0 ~ 1023에 해당하면 음수, 1024 ~ 2047에 해당하면 양수가 저장된다.
- 가수 부분: 52bit로 소수점을 옮겼을 때, 소수점의 오른쪽에 해당하는 부분이다. 왼쪽 부분은 1이기에 따로 저장하지 않고 오른쪽 부분은 계속 순환되기에 52비트에 넣으면 52번째 이후 값은 반올림해야 하고 51번째 값은 0, 52번째 값은 1, 53번째 값은 1인데 53번째에서 반올림하므로 51은 1, 52는 0이 된다. 만약 오른쪽 부분이 52개보다 작다면 0으로 채워 넣는다.
'TIL' 카테고리의 다른 글
TIL - 20221011 (0) | 2022.10.11 |
---|---|
TIL - 20221010 (0) | 2022.10.10 |
TIL - 20221008 (객체와 Map 성능 차이) (0) | 2022.10.08 |
TIL - 20221007 (LRU) (0) | 2022.10.07 |
TIL - 20221006 (비트 연산자) (0) | 2022.10.06 |