개발일지/Front-end

Javascript 숫자와 관련된 사소한 팁

cotnmin 2023. 1. 22. 23:59

1. _로 숫자 구분하기 (numeric separator)

가끔 큰 단위의 숫자를 적는 경우 한눈에 들어오지 않는 경우가 많은데,
이때 언더바(_)를 이용해 숫자를 쉽게 구분해 줄 수 있습니다.

let num1 = 1000000;
let num2 = 1_000_000;
let num3 = 100_0000;
// num1 == num2 == num3

언더바를 입력하는 위치는 꼭 3자리씩 끊어서 표시할 필요는 없습니다.
다만, 아래처럼 두 개를 이어서 나타내지는 못합니다.

let num_err = 100__000;
// Uncaught SyntaxError: Only one underscore is allowed as numeric separator

2. n진법

let num1 = 11; // 10진법: 11
let num2 = 0b11; // 2진법: 3
let num3 = 0o11; // 8진법: 9
let num4 = 011; // 8진법: 9
let num5 = 0x11; // 16진법: 17

위와 같이 n진법 숫자를 바로 입력할 수 있습니다.

반대로 숫자형을 n진법으로 표현하려면 아래와 같이 가능합니다.

let num = 30;
num.toString(); // '30'
num.toString(2); // '11110'
num.toString(8); //'36'
num.toString(16); // '1e'

숫자형을 n진법으로 바꿀 때는 2~36진법까지 원하는 숫자를 입력해 문자열로 변경가능합니다.

3. BigInt

Javascript에서는 숫자는 number 객체입니다. 이는 타 언어의 double 타입과 비슷하게 생각하면 됩니다.
이렇다 보니 123 이런 식으로 정수를 작성해도 Javascript에서는 부동소수점으로 판단합니다.
아무튼 이때 number가 가질 수 있는 가장 큰 값은 2^53 - 1Number.MAX_SAFE_INTEGER9007199254740991 과 같습니다. 이 값보다 큰 값은 연산결과를 신뢰할 수 없게 됩니다.

9007199254740992 == 9007199254740993 // true
9007199254740999 == 9007199254740992 // false

일반적으로는 이 값보다 큰 값을 사용할 일이 드문데, 코테같은걸 풀다 보면 더 큰 정수가 필요한 상황이 생길 수 있습니다.
이때 BigInt를 사용할 수 있습니다.
BigInt(9007199254740992)9007199254740992n 같은 방식으로 사용할 수 있습니다.
BigInt의 몇 가지 특징을 알아보겠습니다.

1. BigInt는 BigInt끼리만 연산 가능

+, *, -, /, %, **, >>, <<, 연산자들을 모두 이용할 수 있고 항상 부호가 있는 값이기에 >>>(unsigned right shift)를 사용할 수 없습니다. 이때 연산은 BigInt끼리만 할 수 있습니다.

console.log(1n + 3n); 
// 4n 
console.log(1n >> 1); 
// Cannot mix BigInt and other types, use explicit conversions 
let i = 1n; 
console.log(++i); 
// 2n

2. BigInt는 부호가 있는 정수값으로 부동소수점을 가지지 않음

let num1 = 23.1n;
// Uncaught SyntaxError: Invalid or unexpected token
let num2 = 5n / 2n;
console.log(num2);
// 2n (소수점 버림)

3. Number값과 대소구분은 가능

console.log(2n === 2);
// false
console.log(2n == 2);
// true

console.log(2n >= 2);  
// true  
console.log(3n < 2.9899291);  
// false

const numbers = [1n, -20n, 9, 0, 10n];  
numbers.sort();  
console.log(numbers);  
// [-20n, 0, 1n, 10n, 9]

numbers.sort((a, b) => a - b);  
// Cannot mix BigInt and other types, use explicit conversions

numbers.sort((a, b) => a > b ? 1 : a < b ? -1 : 0);  
console.log(numbers);  
// [-20n, 0, 1n, 9, 10n]

4. Number와 똑같이 _과 n진법 응용 가능

let num1 = 1_000_000n // 1000000n

let num2 = 11n; // 10진법: 11n
let num3 = 0b11n; // 2진법: 3n
let num4 = 0o11n; // 8진법: 9n
let num5 = 011n; // 8진법: 9n
let num6 = 0x11_11n; // 16진법: 4369n

let num7 = 30n;
num.toString(); // '30'
num.toString(2); // '11110'
num.toString(8); //'36'
num.toString(16); // '1e'

위처럼 Number와 다르지 않게 _과 n진법 활용이 가능합니다.

4. 이상한 자바스크립트?

javascript meme이라고 구글에 검색하면 자바스크립트의 자동형 변환 때문에 생기는 이상한 허점들이 많이 나오는데요

그중 숫자와 관련한 몇 가지를 알아보면

/* 
true는 1과 같지만 타입은 다르다
true를 세번 더하면 타입까지 3이랑 같아진다...
*/
true == 1 // true
true == 3 // false
true === 1 // false
true + true + true === 3 // true

/* 
문자열 'Infinity'는 Infinity와 같지만 타입은 다르다
문자열 'Infinity'에 -를 붙이면 타입까지 Infinity와 같아진다...
*/
'Infinity' == Infinity // true
'Infinity' === Infinity // false
-'-Infinity' === Infinity // true

/*
문자열끼리 연산할 때 더하면 붙이고 뺄땐 빼고...?
*/
2 + 2 - 2 // 2
'2' + '2' - '2' // 20

이 외에도 재미있는(?) 이슈들이 있으니 검색해 보세요. 직접 이런저런 계산하면서 찾아봐도 재미있습니다.

내용에 문제가 있거나 추가할 내용이 있다면 댓글 남겨주세요

참고

v8 - Numeric separators
mdn web docs - Number
mdn web docs - BigInt