자바스크립트 에서의 숫자

자바스크립트에서 일반적인 숫자는 배정밀도 부동소수점 숫자 라고 불리우는 64비트 형식의 IEEE-754에 저장됩니다. 이점을 상기합시다.

숫자를 입력하는 다양한 방법

console.log(5e6); //5000000
console.log(5.2e-6); //0.0000052

10의 지수를 e로 나타냄으로서 길게 늘어뜨릴 숫자를 쉽게 표현할 수 있습니다.

2, 8, 16진수 표현법

2진수는 0b를 이용해서, 8진수는 0o를 사용해서 표현이 가능합니다만 자주 쓰이지는 않습니다.
16진수는 색을 나타내거나 문자를 인코딩할 때 등 다양한 곳에서 많이 쓰입니다.
16진수는 0x를 이용해서 짧게 표현이 가능합니다.

console.log(0b1111); // 15
console.log(0o26); // 22 

console.log(0x11); // 17
console.log(0xa); // 10
console.log(0xb); // 11
console.log(0xc); // 12 
console.log(0xd); // 13
console.log(0xe); // 14
console.log(0xf); // 15

Number.toString()

Number객체에 한해서 toString(base)는 매개변수안에 표현하고 싶은 진법을 입력하면 해당 진법으로 숫자를 변환해서 문자열로 반환해줍니다. 때에 따라서 굉장히 매력적인 함수로 쓰입니다.

const num = 10;
console.log(num.toString(2));// 1010

어림수 구하기

Math.floor(Number)

이런 종류의 함수는 매개변수가 숫자형 하나 입니다. .floor()은 인수로 받은 숫자의 첫번째 소수점에서 내려서 정수로 반환합니다.

console.log(Math.floor(-1.2)) // -2

Math.ceil(Number)

.ceil()은 인수로 받은 숫자의 첫번째 소수점에서 올려서 정수로 반환합니다.

console.log(Math.ceil(-1.2)) // -1

Math.round(Number)

.round()은 인수로 받은 숫자의 첫번째 소수점에서 반올림을 하여 정수로 반환합니다.

console.log(Math.round(-1.2)) // -1

Math.trunc(Number)

.trunc()은 인수로 받은 숫자의 소수부를 무시하여 정수로 반환합니다.

console.log(Math.trunc(-1.2)) // -1

Number.toFixed(size)

.toFixed()는 해당 숫자의 소수점 size만큼 Math.round와 같이 가장 가까운 수로 어림수를 구한다음 문자열로 반환합니다.

const num = 10;
console.log(num.toFixed(3)); // `10.000`
const num2 = 0.13123145412;
console.log(num2.toFixed(3)); // `0.131`

부정확한 계산

숫자는 내부적으로 64비트로 저장되기 때문에 IEEE-754형식에서 52비트는 숫자를 저장하는데 사용되고 11비트는 소수점의 위치를 (정수는 0), 1비트는 부호를 위해 사용됩니다.

그런데 숫자나 너무나 길면 64비트의 공간이 넘쳐서 Infinity로 표시됩니다.

console.log(1e500); // Infinity

정밀 손실도

숫자는 0과 1인 이진수로 변환되어 연속된 메모리 공간에 저장됩니다. 이진수로 표현되므로 2의 거듭제곱이 아닌수는 딱떨어지지 않습니다.

예를 들면 10진수로 1/ 10은 0.1으로 표현하면 딱 떨어집니다. 하지만 1/3은 10의 거급제곱이 아니기 때문에 딱떨어지지 않습니다. 이와 같은 이유로 아주작은 정밀도의 손실이 일어납니다. 아래와 같은 정밀도 손실은 자바스크립트 뿐만 아니라 다른언어들에서도 일어납니다. IEEE-754는 저장시 가장가까운수로 반올림하여 저장하면서 이런 손실을 최소화 합니다만 그래도 일어납니다.

console.log(0.1 + 0.2); // 0.30000000000000004

이러한 손실을 방지하기 위해서 소수점 끼리의 연산후에는 반드시 .toFixed()를 해주어 이러한 손실을 정확하게 끝내버립니다. 필요한 마지막 연산에서 이렇게 필요할 때마다 꼬리를 잘라줍니다.

isNaN() & isFinite()

isNaN()은 값이 NaN 이면 true, 아니면 false를 반환합니다. 다만 NaN은 특이하게 자기자신을 포함해서 그 어느것도 같지 않은 에러를 나타냅니다.

NaN 은 Not a Number의 JS 표현입니다.

console.log(isNaN(NaN)); // true
console.log(NaN === NaN); // false

isFinite()은 인수를 숫자로 변환하고 변환한 값이 NaN, Infinity, -Infinity 이면 false, 그외 이면 true를 반환합니다. 따라서 입력된 숫자가 사용 가능한 숫자인지 아닌지 판별할때 자주 사용됩니다.

console.log(isFinite('21312')); // true
console.log(isFinite('doodrema')); // false

parseInt(), parseFloat()

문자열에서 숫자만을 긁어오는 함수가 필요할때 사용합니다. 문자열에서 숫자만을 추출하다가 에러가 나면 수집된 숫자까지만 숫자로 반환합니다.

문자열에서 숫자가 나오다가 다른 문자열이 나오면 즉 에러가 나면 숫자 수집을 멈추고 숫자를 반환합니다.

console.log(parseInt('100.101px')); // 100
console.log(parseFloat('100.101px')); // 100.101
console.log(parseInt('100px, 200px'));// 100

BigInt

const newNum = 20123412341341341234123412341234n;
const newNum2 = BigInt('12351543657898746782948576748');
const newNum3 = BigInt(1235154365789874678294857674135135);
console.log(typeof newNum); //bigint
console.log(typeof newNum2); //bigint
console.log(typeof newNum3); //bigint
console.log(newNum + 1); // Cannot mix BigInt and other types, use explicit conversions

BigInt라는 타입은 최근에 업데이트된 자바스크립트 문법입니다. 위에서 말했듯 자바스크립트는 IEEE-754라는 64비트에 숫자를 저장하기 때문에 긴 숫자는 짤라서 저장하거나 Infinity라는 것으로 저장을 해버리는데요, BigInt는 이러한 제약을 없애주는 자료형입니다.

일반적인 숫자의 끝에 n을 붙여주거나 BigInt()이렇게 형변환을 해주거나 하면됩니다. 해당 함수의 매개변수로서는 숫자로 변환가능한 숫자 문자열이나 숫자가 들어가면됩니다.

BigInt은 해당 자료형 끼리는 특별히 일반숫자와 큰차이 없이 사용할 수 있습니다. BigInt형을 반환하기 때문입니다. 하지만 다른특징은 일반적인 숫자랑은 자료형이 다르기 때문에 사칙연산이 일반숫자와 섞어서 사용할수 없습니다.

BigInt를 일반숫자와 계산하기 위해서는 Number()을 사용하거나, 일반숫자를 BigInt()로 형변환을 하여 계산해야합니다.

추가로 BigInt는 단항 덧셈 연산자 사용이 불가능합니다. 하지만 일반 숫자와의 비교연산은 가능합니다. 또한 논리 연산자에서 boolean으로 형변환시에도 일반 숫자와 동일하게 취급 받습니다.

+ 연산자는 앞에서 쓰이면 쉽게 숫자형으로 바꿀수 있습니다. 숫자 자체에는 아무런 영향을 끼치지 않으나 형변환이 이뤄지게 됩니다.

console.log(+''); // 0
console.log(+'2'); // 2
console.log(+1); // 1
console.log(+-1); // -1
const newNum = 20123412341341341234123412341234n;
console.log(+newNum);// Cannot convert a BigInt value to a number
console.log(newNum > 1);// true
newNum && console.log('bigInt work'); // bigInt work

Intl 국제화 서식

나라마다 날짜 표준의 기준이 다르다. 미국은 월 일 년도 순이고 우리나라는 년도 월 일 순이다. 시리야 같은경우에는 아라비아 숫자를 안쓰고 해당 나라 말로 표시하기도 한다. 이러한 표준을 기준으로 자동으로 해당지역의 문자열로 넘겨주는 기능을 하는 것이 Intl.DateTimeFormat()이다.

const now = new Date();
console.log(Intl.DateTimeFormat('kr-KR').format(now));
// 2021. 5. 4.

Intl.DateTimeFormat(iso language code table).format(new Date())

iso language code table은 아래 문서를 참조하면 원하는 지역의 서식으로 현재날짜를 출력할수 있다.

iso language code table 링크

하지만 이러한 설정은 자연스럽게 사용자의 브라우저에서 사용자의 사는 지역의 iso language code를 가져올수 있다.

const locale = navigator.language;
console.log(locale); // ko-KR

추가로 옵션을 넣을 수도 있다. 원하는 서식으로 출력되게끔 말이다.

const locale = navigator.language;
const options = {
  minute: 'numeric',
  hour: '2-digit',
  day: 'numeric',
  month: 'long',
  year: 'numeric',
  weekday: 'long',
};
const now = new Date();
console.log(Intl.DateTimeFormat(locale, options).format(now));
//2021년 5월 4일 화요일 오전 11:52

Intl로 다른 여러가지 서식도 변경이 가능하다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Intl

위 사이트에서 문서를 참고하면 된다.

profile
일상을 기록하는 삶을 사는 개발자 ✒️ #front_end 💻

0개의 댓글