자바스크립트에서는 숫자를 어떻게 다룰까?
또한, 태그된 템플릿은 뭘까?
이 글에서 알아볼 것
- 자바스크립트에서의 Number 객체와, 부동 소수점
- BigInt
- 태그된 템플릿
1. 자바스크립트에서의 Number 객체와, 부동 소수점
- 자바스크립에서의 Number는 모두 부동 소수점 숫자(Float)로 이루어져있다
- 즉, 자바스크립트에는 다른 언어의 Integer같은 소숫점이 없는 Number는 존재하지 않는다
- 모든 Number는 64비트 부동 소수점 수로 저장된다
- 이러한 Number에는 최대값과 최솟값이 존재하고, 정밀도에도 한계가 존재한다
console.log(Number.MAX_SAFE_INTEGER);
// 최대 정수값 => 9007199254740991 (2^53 -1)
console.log(Number.MIN_SAFE_INTEGER);
// 최소 정수값 => -9007199254740991
console.log(Number.MAX_VALUE);
// 최대값 => 1.7976931348623157e+308
console.log(Number.MIN_VALUE);
// 최솟값 => 5e-324
- 부동 소수점의 (부)정확성
- 자바스크립트에서 0.2 + 0.4의 결과가 0.600…0001으로 도출된다, 왜 그럴까?
- 자바스크립트는 다른 언어와 마찬가지로 2진법을 사용한다
- 10진법에서도 1/3 = 0.33333…..처럼 정확한 결과를 도출할 수 없는 것이 존재하듯, 2진법에도 존재한다.
- ex) (0.2).toString(2) ⇒ 0.001100…..
- 그러면 이런 부정확함이 문제점일까? 일반적으로 아니다
- 자바스크립트 또는 대부분의 언어에서 자동으로 반올림 처리를 해주어 사람이 인식하기에 문제가 없는 계산 결과를 도출해준다 (또는 toFixed()를 통해 직접 고정도 가능)
- 하지만, 만약 쇼핑몰같은 곳에서 물건값이 $20.2라면 자바스크립트는 20.2~~~~이라는 값으로 인식하기때문에 문제가 발생할 수도 있다.
- 이때 해결방법으로 가장 간단한건 * 100등을 하여 정수로 만들어 버리고 처리하는 것이다
- 또는, 패키지나 라이브러리의 도움을 받을 수 있다
- 자바스크립트에서 0.2 + 0.4의 결과가 0.600…0001으로 도출된다, 왜 그럴까?
2. BigInt
1번에서 다룬 코드를 살펴보면,
자바스크립트에서 표현할 수 있는 최대 정수값은 9007199254740991 이다.
근데 만약, 무조건 여기에 수를 더하여 더 큰수를 구해야할 상황이 발생하면 어떻게 해야할까?
- 이러한 문제를 해결하기 위해, 최신 자바스크립트에는 정규수를 표현하는 새로운 방법을 제시되었는데, 그것이 바로 BigInteger 타입이다
- BigInt란?
- 원시 타입에 해당하며, MAX_SAFE_INTEGER로 표현할 수 있는 숫자보다 더큰 숫자를 다룰때 사용된다
- 위에서 예를든 것을 해결할 수 있다.
- 원래라면 9007199254740991 + 1 = 9007199254740992가 아닌 다른 이상한 숫자가 도출되지만, BigInt를 활용하면, 즉 9007199254740991n + 1n = 9007199254740992n 으로 정확하게 계산된다.
- 이게 가능한 이유는 BigInt 타입은 숫자 뒤에 n을 붙이는데, n을 붙이면 64비트의 부동소수점이아니라 문자열로 인식하기 때문이다
- BIg"Int"라는 이름처럼 정수만 가능하다(소수점 못붙임), 다른 Number와 계산 불가능 하다 (10n + 1 ⇒ 불가능)
- Number와 BigInt끼리 계산하려면 parseInt로 BigInt를 바꾸거나, BigInt()로 Number를 바꿔서 계산해야함
- 5n/2n = 2n다 (결과값도 정수만을 도출한다)
3. 태그된 템플릿
앞에서 살펴봤듯, 자바스크립트에서 동적인 값을 문자열과 같이 활용할 때 백틱(``)을 활용하고, 이를 템플릿 리터럴이라 부른다는 것을 잘 알고있다.
그렇다면 만약, 함수에 인풋이(인자가) 복잡한 템플릿 리터럴이라 가정할때,
함수에서 템플릿 리터럴에서의 문자열과 동적인 값을 각각 분리해서 사용하고 싶다면 어떻게 해야할까?
이때 사용되는 구문이 태그된 템플릿이다.
const dummyFn = (string, pName, pPrice) => {
return "Hi, Messi!"
}
const prodName = "Javascript"
const prodPrice = 29.99
const dummyOutput = dummyFn`This product ${prodName} is $${prodPrice}.`
위의 코드 마지막 부분을 보자
이상하게 생겨서 당황할 수도 있지만,
천천히 살펴보면 결국 함수를 상수에 저장한것이고, 함수에 인자값을 템플릿 리터럴로 넣어준것이다.
이처럼 태그된 템플릿은 함수에 템플릿 리터럴을 인풋값으로 넘겨주는 것을 뜻한다.
그럼 다시 코드로 돌아와서 구성을 살펴보면
- 함수는 3가지 인자를 받는데,
- 첫번째 인자(string) -> 항상 템플릿 리터럴에서 동적인 값을 뺀 문자열 부분이다.
- string을 console.log()로 찍어보면 [This product, is $, .] 을(배열) 반환한다는 것을 알 수 있다.
- 두번째 인자, 세번째 인자 -> 동적인 부분이다.
- 첫번째 인자(string) -> 항상 템플릿 리터럴에서 동적인 값을 뺀 문자열 부분이다.
const dummyFn = (string, pName, pPrice) => {
let priceCategory = "cheep"
if (pPrice > 20) {
priceCategory = "fair"
}
return `${string[0]}${pName}${string[1]}${priceCategory}${string[2]}`
}
const prodName = "Javascript"
const prodPrice = 29.99
const dummyOutput = dummyFn`This product ${prodName} is $${prodPrice}!`
- 또는 위처럼 객체를 활용해 동적인값만 추출하고싶을때도 사용된다.
이번 글에서 살펴본 내용들은 어떻게 보면 다른 내용들에 비해서 중요도가 떨어지는 것처럼 보여질 수도 있지만,
"자바스크립트의 모든 Number는 부동소수점이다" , BigInt에 대한 이해, 태그된 템플릿 사용법등 알아야 할 것들도 존재하기 때문에 간단하게 정리해보았다.
'OLD > Javascript' 카테고리의 다른 글
[Javascript] 자바스크립트 HTTP 통신 (XMLHttpRequest vs fetch() vs axios ...) (0) | 2023.02.26 |
---|---|
[Javascript] 자바스크립트 비동기(Async)_01 (sync & async 코드, 이벤트 루프, 콜백함수, async / await 키워드) (0) | 2023.02.25 |
[Javascript] 자바스크립트 고급 함수 (순수 함수 & 부수 효과, 팩토리 함수, 클로저) (0) | 2023.02.23 |
[Javascript] 자바스크립트 이벤트(preventDefault(), 버블링(Bubbling) & 캡쳐링(Capturing), 드래그 & 드롭) (2) | 2023.02.22 |
[Javscript] 자바스크립트 this (0) | 2023.02.21 |