Skip to content

Commit 37ec3b0

Browse files
committed
docs: JavaScript - Number Type Issues (#3)
1 parent b5f3476 commit 37ec3b0

File tree

2 files changed

+104
-1
lines changed

2 files changed

+104
-1
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# JavaScript에서 Number 타입의 문제점
2+
3+
## Summary
4+
5+
JavaScript의 `Number` 타입은 IEEE 754 부동 소수점 표준을 기반으로 동작하며, 정밀도 문제, 안전한 정수 범위, 연산 오류 등의 한계를 가지고 있다. 이를 이해하고 적절한 대처법을 적용하는 것이 중요하다.
6+
7+
## Details
8+
9+
### Number 타입 개요
10+
11+
- JavaScript에서 `Number` 타입은 **64비트 IEEE 754 배정도 부동 소수점 형식**을 사용한다.
12+
- 정수와 실수를 구분하지 않고 동일한 `Number` 타입으로 관리된다.
13+
14+
```javascript
15+
console.log(typeof 10); // 'number'
16+
console.log(typeof 10.5); // 'number'
17+
```
18+
19+
### 정밀도 문제
20+
21+
- JavaScript의 `Number` 타입은 소수를 정확하게 표현하지 못하는 경우가 많다.
22+
- 이는 IEEE 754 부동 소수점 표준에서 **이진수 변환 시 발생하는 오차** 때문이다.
23+
24+
```javascript
25+
console.log(0.1 + 0.2); // 0.30000000000000004
26+
console.log(0.1 + 0.2 === 0.3); // false
27+
```
28+
29+
#### **왜 0.1 + 0.2가 0.3이 아닌가?**
30+
- 0.1과 0.2는 이진수로 정확하게 표현될 수 없는 값이다.
31+
- 실제 내부 저장 방식은 다음과 같다.
32+
- `0.1``0.00011001100110011001100110011001100110011001100110011... (2진수)`
33+
- `0.2``0.0011001100110011001100110011001100110011001100110011... (2진수)`
34+
- 이진수 연산 결과가 정확히 0.3이 되지 않기 때문에 오차가 발생한다.
35+
36+
### 안전한 정수 범위
37+
38+
JavaScript의 `Number` 타입은 **안전한 정수(Safe Integer)** 를 다음 범위 내에서만 정확하게 표현할 수 있다.
39+
40+
![Image](https://github.com/user-attachments/assets/d45aee2d-e1ca-46bb-9dd8-fcd289b26406)
41+
42+
```javascript
43+
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
44+
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
45+
```
46+
47+
이 범위를 벗어나면 연산 결과가 부정확할 수 있다.
48+
49+
```javascript
50+
console.log(9007199254740991 + 1); // 9007199254740992
51+
console.log(9007199254740991 + 2); // 9007199254740992 (잘못된 결과)
52+
```
53+
54+
### 연산 오류
55+
56+
부동 소수점 연산에서 발생하는 오류 중 하나는 **0과 -0의 구분**이다.
57+
58+
```javascript
59+
console.log(1 / 0); // Infinity
60+
console.log(1 / -0); // -Infinity
61+
```
62+
63+
`-0``0`은 비교 연산에서는 같지만, 연산 결과는 다를 수 있다.
64+
65+
### 해결 방법
66+
67+
#### **1. BigInt 사용**
68+
- `BigInt`는 정수를 안전하게 표현하는 별도의 데이터 타입이다.
69+
- `n`을 붙여서 `BigInt` 타입으로 변환할 수 있다.
70+
71+
```javascript
72+
console.log(9007199254740991n + 2n); // 9007199254740993n
73+
```
74+
75+
- 단, `BigInt``Number`와 혼합해서 사용할 수 없다.
76+
77+
```javascript
78+
console.log(10n + 5); // TypeError: Cannot mix BigInt and other types
79+
```
80+
81+
#### **2. 라이브러리 활용**
82+
- 부동 소수점 오차를 방지하기 위해 `decimal.js`, `big.js`, `bignumber.js`와 같은 라이브러리를 사용할 수 있다.
83+
84+
```javascript
85+
const Big = require('big.js');
86+
console.log(new Big(0.1).plus(0.2).toString()); // "0.3"
87+
```
88+
89+
## Reference
90+
91+
**issue**: Related issue in this repo
92+
- [JavaScript의 number는 왜 0과 -0을 지원하는가?](https://github.com/luke0408/TIL/issues/3)
93+
94+
**author note**: Related note in this repo
95+
- [JavaScript - number](./Number.md)
96+
- [IEEE 754 Floating Point](../../../DevGeneral/IEEE/IEEE_754_Floating_Point.md)
97+
98+
**link:** External reference
99+
- [MDN Web Docs: Number](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Number)
100+
- [ECMAScript Number 객체](https://tc39.es/ecma262/multipage/fundamental-objects.html#sec-number-objects)
101+
- [What Every Computer Scientist Should Know About Floating-Point Arithmetic (David Goldberg, 1991)](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)
102+
- [The Floating-Point Guide](https://floating-point-gui.de/)

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
| DevOps | DevOps와 관련된 내용 | 0 |
1212
| Databases | 데이터베이스와 관련된 내용 | 0|
1313
| Frontend | 프론트 프레임워크와 관련된 내용 | 0 |
14-
| Languages | 다양한 프로그래밍 언어와 관련된 내용 | 20|
14+
| Languages | 다양한 프로그래밍 언어와 관련된 내용 | 21|
1515
| Networking | 네트워킹과 관련된 내용 | 0|
1616
| OperatingSystems | 운영 체제와 관련된 내용 | 1|
1717
| Security | 보안과 관련된 내용 | 0|
@@ -70,6 +70,7 @@
7070
┃  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃  &nbsp;&nbsp;┣━&nbsp;📄[**Boolean**](./Languages/JavaScript/DataTypes/Boolean.md)</br>
7171
┃  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃  &nbsp;&nbsp;┣━&nbsp;📄[**Null**](./Languages/JavaScript/DataTypes/Null.md)</br>
7272
┃  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃  &nbsp;&nbsp;┣━&nbsp;📄[**Number**](./Languages/JavaScript/DataTypes/Number.md)</br>
73+
┃  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃  &nbsp;&nbsp;┣━&nbsp;📄[**Number_Type_Issues**](./Languages/JavaScript/DataTypes/Number_Type_Issues.md)</br>
7374
┃  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃  &nbsp;&nbsp;┣━&nbsp;📄[**String**](./Languages/JavaScript/DataTypes/String.md)</br>
7475
┃  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃  &nbsp;&nbsp;┣━&nbsp;📄[**Symbol**](./Languages/JavaScript/DataTypes/Symbol.md)</br>
7576
┃  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;┃  &nbsp;&nbsp;┗━&nbsp;📄[**Undefined**](./Languages/JavaScript/DataTypes/Undefined.md)</br>

0 commit comments

Comments
 (0)