LHJ

I'm a FE developer.

3.6 숫자

18 Apr 2020 » js_lj

3이나 5.5, 1,000,000처럼 컴퓨터가 정확히 나타낼 수 있는 숫자도 있지만, 근사치로만 표현할 수 있는 숫자도 많습니다.
예를 들어π는 절대 컴퓨터로 표현할 수 없습니다.
원주율을 구성하는 숫자는 무한하고 반복되지도 않기 때문입니다.
10/3 같은 숫자는 특별한 테크닉을 써서 나타낼 수 있긴 하지만, 소수점 아래 자리가 무한히 반복되므로(3.3333….) 일반적으로 근사치로만 나타냅니다.

자바스크립트도 다른 프로그래밍 언어와 마찬가지로 실제 숫자의 근사치를 저장할 때 IEEE-764배정도(double-precision) 부동소수점 숫자 형식을 사용합니다.
앞으로는 이 형식을 ‘더블’ 이라고 부를 겁니다.
이 형식의 세부 사항은 이 책의 범위를 벗어납니다.
하지만 자바스크립트로 심도 있는 숫자형 분석을 하지 않는 한 더블 형식을 이해할 필요는 별로 없습니다.

그런데 더블 형식의 근사치 결과는 종종 사람들을 당혹스럽게 만들곤 합니다.
예를 들어 자바스크립트에서 0.1 + 0.20.30000000000000004를 반환합니다.
이 결과는 자바스크립트에 버그가 있거나 덧셉을 할 줄 몰라서가 아닙니다.
이건 무한한 값을 유한한 메모리 안에서 가능한 한 정확히 짐작하려다가 생긴 결과일 뿐입니다.

자바스크립트에는 숫자형 데이터 타입이 하나밖에 없는데, 이건 흔치 않은 일입니다.
(이런 상황은 나중에 바뀔 수도 있습니다. 세분화된 정수 타입은 꼭 필요한 기능입니다.)
대부분의 프로그래밍 언어는 여러 가지 정수 타입을 사용하며 부동소수점 숫자 타입도 두 가지 이상 사용합니다.
숫자형 데이터를 하나만 갖기로 한 선택은 자바스크립트를 단순한 언어로, 특히 초보자에게 부담 없는 언어로 만들었다는 장점이 있습니다.
반면, 자바스크립트를 고성능 정수 연산이나 정밀한 소수점 연산이 필요한 애플리케이션에서 쓸 수 없게 만든 선택이기도 합니다.

자바스크립트는 10진수, 2진수, 8진수, 16진수의 네 가지 숫자형 리터럴을 인식합니다.
10진 리터럴에는 소수점 없는 정수, 소수점 있는 10진수(12.34 등), 과학에서 사용하는 지수 표기법을 쓸 수 있습니다.
그 외에도 무한대, 음의 무한대, ‘숫자 아님’을 나타내는 특별한 값들이 있습니다.
엄밀히 말해 이들은 숫자형 리터럴이 아니지만, 숫자형 값이므로 여기 포함했습니다.

let count = 10;             // 숫자 리터럴, count는 더블입니다.
const blue = 0x0000ff;      // 16진수, 16진수 ff는 10진수 255와 같습니다.
const umask = 0o0022;       // 8진수, 8진수 22는 십진수 18과 같습니다.
const roomTemp = 21.5;      // 십진수
const C = 3.0e6;            // 지수 (3.0 x 10^6 = 3,000,000)
const e = -1.6e-19;         // 지수 (-1.6 x 10^-19 = 0.00000000000000000016)
const inf = Infinity;
const ninf = -Infinity;
const nan = NaN;            // "숫자가 아님"

TIP 10진수, 16진수, 지수 등 어떤 리터럴 형식을 사용하더라도 결국 숫자는 더블 형식으로 저장됩니다.
다양한 리터럴 형식은 숫자를 간편한 형식으로 표현할 수 있도록 제공된 것뿐입니다.
자바스크립트가 표시할 수 있는 숫자 형식에는 제한이 있습니다. 이에 대해서는 16장에서 설명합니다.

독자 중에 수학자가 있다면 무한대는 숫자가 아니라고 주장할 겁니다.
물론 무한대는 숫자가 아닙니다.
NaN도 숫자는 아닙니다.
이들은 계산에 사용하는 숫자라기보다는 일종의 플레이스홀더입니다.

또한 숫자에 대응하는 Number 객체에는 중요한 숫자형 값에 해당하는 유용한 프로퍼티가 있습니다.

const small = Number.EPSILON; 
// 1에 더했을 때 1과 구분되는 결과를 만들 수 있는
// 가장 적은 값입니다. 근사치는 2.2e-16입니다.
const bigInt = Number.MAX_SAFE_INTEGER;
// 표현할 수 있는 가장 큰 정수
const max = Number.MAX_VALUE;
// 표현할 수 있는 가장 큰 숫자
const minInt = Number.MIN_SAFE_INTEGER; 
// 표현할 수 있는 가장 작은 정수
const min = Number.MIN_VALUE;
// 표현할 수 있는 가장 작은 숫자
const nInf = Number.NEGATIVE_INFINITY;
// -Infinity
const nan = Number.NaN;
// NaN
const inf = Number.POSITIVE_INFINITY;
// Infinity

이들의 중요성에 대해서는 16장에서 설명합니다.