191019_TIL(Number in JS)

자바스크립트의 숫자

숫자 체계

자바스크립트에서 숫자를 표현할 때 64비트 부동 소수점 표현을 사용한다. 부호 비트(63번째 비트)가 1이면 해당 숫자가 음수다. 다음 여덟개의 비트(63번째부터 52번째 비트)는 지수 값 e를 나타낸다. 마지막으로 나머지 52비트가 분수 값을 나타낸다.

십진분수로 인해 자바스크립트에서 부동소수점 체계가 반올임 오류를 일으킬 수 있다.

1
2
// 0.1과 0.2를 정확하게 표현할 수 없다.
0.1 + 0.2 === 0.3 // false

0.1을 부동소수점 숫자로 제대로 표현할 수 없는 이유를 이해하기 위해서는 이진 표기법을 이해해야 한다. 이진 표기법으로 십진수를 표현할 때 무한 개의 수가 필요한 경우가 많다.

자바스크립트 숫자 객체

정수 반올림

자바스크립트에서 모든 숫자를 나타낼 때 부동소수점을 사용하기 때문에 정수 나눗셈을 소용이 없다. 자바에서는 5/4의 결과로 1이 반환된다. 하지만 자바스크립트에서는 1.25가 반환된다.

자바스크립트에서 정수 나눗셈을 하기 위해서는 다음 중 하나를 사용하면 된다.

1
2
3
4
5
6
7
8
9
10
11
Math.floor(0.9); // 0
Math.floor(1.1); // 1

Math.round(0.49); // 0
Math.round(0.5); // 1
Math.round(2.9); // 3

Math.ceil(0.1); // 1
Math.ceil(0.9); // 1
Math.ceil(21); // 21
Math.ceil(21.01); // 22

Number.EPSILON

Number.EPSILON은 두 개의 표현 가능한 숫자 사이의 가장 작은 간격을 반환한다. 이는 부동소수점 근사치를 활용해 분수가 제대로 표현되지 않는 문제를 해결하는데 유용하다.

1
2
3
4
5
function numberEquals(x, y) {
return Math.abs(x - y) < Number.EPSILON;
}

numberEquals(0.1 + 0.2, 0.3); // true

0.1+0.2와 0.3의 차이는 Number.EPSILON보다 작을 것이다.

최대치

Number.MAX_SAFE_INTEGER는 가장 큰 정수를 반환한다.

1
2
3
Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2; // true

Number.MAX_SAFE_INTEGER + 1.111 === Number.MAX_SAFE_INTEGER + 2.022; // false

Number.MAX_VALUE는 가장 큰 부동 소수점을 반환한다.

1
2
3
Number.MAX_VALUE + 1 === Number.MAX_VALUE + 2; // true

Number.MAX_VALUE + 1.111 === Number.MAX_VALUE + 2.022; // true

최소치

Number.MIN_SAFE_INTEGER는 가장 작은 정수를 반환한다.

Number.MIN_SAFE_INTEGER는 -9007199254740991이다.

1
2
3
Number.MIN_SAFE_INTEGER - 1 === Number.MIN_SAFE_INTEGER - 2; // true

Number.MIN_SAFE_INTEGER - 1.111 === Number.MIN_SAFE_INTEGER - 2.022; // false

Number.MIN_VALUE는 가능한 가장 작은 부동소수점 수를 반환한다.

Number.MIN_VALUE 는 5e-324이다. Number.MIN_VALUE는 음수가 아니다. Number.MIN_VALUE는 0에 가장 가까운 부동소수점이다.

1
Number.MIN_VALUE - 1 == -1; // true

위 코드는 0 - 1 == -1과 비슷하다.

무한

Number.MAX_VALUE보다 큰 유일한 것은 Infinity이고 Number.MIN_SAFE_INTEGER보다 작은 유일한 것은 -Infinity이다.

1
2
3
Infinity > Number.MAX_VALUE; // true
-Infinity < Number.MIN_SAFE_INTEGER // true
-Infinity -32323323 == -Infinity -1; // true

크기 순서

1
-Infinity < Number.MIN_SAFE_INTEGER < 0 < Number.MIN_VALUE < Number.MAX_SAFE_INTEGER < Number.MAX_VALUE < Infinity

숫자 알고리즘

소수 테스트

  • 2의 배수는 무시해도 된다.
  • 소수 중 2와 3을 제외하고는 6k +- 1의 형태를 지닌다.
  • n이 소수인지 알아보기 위해서는 반복문을 제곱근까지만 확인해보면 된다. n의 제곱근이 소수가 아니면 n은 수학 정의에 의해 소수가 아니기 때문이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
function isPrime(n) {
if (n <= 1) return false;
if (n <= 3) return true;

if (n % 2 == 0 || n % 3 == 0) return false;

for (var i = 5; i * i <= n; i = i + 6) {
if (n % i == 0 || n % (i + 2) == 0)
return false;
}

return true;
}

시간 복잡도 O(sqrt(n))

소인수분해

소수는 암호화와 해싱의 기반이 된다. 소인수분해는 주어진 숫자를 만들기 위해 어떤 소수들이 곱해져야 하는지 구하는 과정이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function primeFactors(n) {

while (n % 2 == 0) {
console.log(2);
n = n / 2;
}

for (var i = 3; i * i <= n; i = i + 2) {
// While i divides n, print i and divide n
while (n % i == 0) {
console.log(i);
n = n / i;
}
}

if (n > 2) {
console.log(n);
}
}

시간 복잡도 O(sqrt(n))

무작위 수 생성기

Math.random()은 0과 1사이의 부동소수점을 반환한다.

1
2
3
Math.random() * 100; // 0부터 100까지의 부동소수점
Math.random() * 25 + 5; // 5부터 30까지의 부동소수점
Math.random() * 10 - 100; // -100부터 -90까지의 부동소수점

무작위 정수를 얻기위해서는 Math.floor(), Math.round(), Math.ceil()을 사용한다.

1
2
3
Math.floor(Math.random()) * 100;// 0부터 99까지의 정수
Math.round(Math.random()) * 25 + 5; // 5부터 30까지의 정수
Math.ceil(Math.random()) * 10 - 100; // -100부터 -90까지의 정수
Share