javascript에서 Numbers는 원시타입중 하나로 "이중 정밀도 64비트 형식 IEEE 754 값"으로 정의됩니다.
여기서 말하는 이중 정밀도란 컴퓨터에서 소수점을 표현하는 방식 중 하나인 부동 소수점 방식중 하나로 부동 소수점 방식은 4바이트의 단일 정밀도 형식과 8바이트의 이중 정밀도 형식으로 나뉩니다.
컴퓨터에서 실수를 부동 소수점 방식으로 저장하면 부호 비트와 지수 부분과 가수 부분이 아래와 같은 공식으로 저장됩니다.
m X r^e ( m : 가수 r : 밑수 e : 지수 )
부호 비트는 양의 실수인지 음의 실수인지 나타내는 부분이고, 지수 부분은 소수점 위치를 나타내며, 가수 부분은 유효 자릿수를 나타냅니다.
32비트 체제(단일 정밀도 형식)에서는 부호 부분 1, 지수 부분 8, 가수 부분 23개로 비트를 할당합니다.
64비트 체제(이중 정밀도 형식)에서는 부호 부분 1, 지수 부분 11, 가수 부분 52개로 비트를 할당합니다.
실수를 부동 소수점 방식으로 저장할 때는 정규화 과정을 거칩니다. 예를 들어 2진 소수 101.01 x 2^1은 10.101 x 2^2로 표현해도 값이 변하지 않습니다. 이때 정규화된 표현은 1.0101 x 2^3입니다. 이와 같이 2진 소수를 정규화시키면 1.xxx로 표현할 수 있습니다. 정규화된 2진 소수 1.0101 x 2^3의 부호는 양수, 가수는 1.0101, 밑수는 2, 지수는 3입니다.
정보를 저장할 때 양의 지수와 음의 지수가 구분되도록 단일 정밀도일 때는 지수에 127을 더하고 이중 정밀도일 때는 1023을 더합니다. 그리고 가수에는 정수 값 1을 생략하고 저장합니다.
위 정규화 과정과 비트 정리 과정을 거치게 되면 부동 소수점 표현이 가능합니다.
2진수 10110.11011을 단일 정밀도 형식의 부동 소수점으로 나타내 봅시다.
2진수 10110.11011을 정규화하면 1.011011011 x 2^4가 됩니다. 부호 비트는 양수이므로 0, 지수는 4이므로 바이어스에 적용하면
127 + 4 = 131이 됩니다. 결과적으로 10000011(2) = 131(10)이 됩니다.
가수는 정수 값 1을 제외한 011011011을 저장하고 나머지 0으로 채우므로 변환된 부동 소수점 표현은 아래와 같습니다.
( 부동 소수점 ) 0 10000011 00000000000000011011011
여기까지가 javascript Numbers에 사용되는 이중 정밀도 64비트에 대한 설명이었고 이제 IEEE 754에 대해 말씀드리겠습니다.
IEEE 754는 부동 소수점을 표현하는 표준 방식 중 하나로 무한, NaN 등의 기호를 표시하는 법과 이러한 수에 대한 연산을 정의하고 있습니다.
IEEE 754에는 32비트 단일 정밀도(single-precision), 64비트 이중 정밀도(double-precision), 43비트 이상의 확장 단정밀도(거의 쓰이지 않음), 79비트 이상의 확장 배정밀도(일반적으로 80비트로 구현됨)에 대한 형식을 정의하고 있습니다. 많은 프로그래밍 언어에서 IEEE 표준을 따르도록 정의하고 있으며, 예를 들어 C에서는 float는 단일 정밀도, double은 이중 정밀도와 대응됩니다.
IEEE 754 부동 소수점 표현 방식은 다음과 같습니다.
- 산술 형식: 유한한 수들(0을 포함한)과 무한대와 NaN(Not a number) 값으로 구성된 2진수와 10진수의 부동 소수점 데이터 집합
- 형식의 교환: 부동 소수점 데이터를 효율적이고 압축적으로 전환할 수 있는 인코딩
- 반올림 규칙: 산수와 전환의 과정에서 반올림할 때의 성질
- 작동: 산수와 산술 형식의 처리 방법 형식
- 예외 처리: 예외적인 조건의 표기 (0으로 나누는 작업, 오버플로 등)
IEEE 754에 이 외에도 더 복잡한 예외 처리, 추가적인 작업(삼각함수 등), 표현의 평가, 그리고 생산 가능한 결과의 성취를 위한 여러 방법이 포함되어 있다.
여기까지 읽었다면 "이중 정밀도 64비트 형식 IEEE 754 값"에 대한 의미를 이해하셨을 거라 생각합니다.
jacascript에는 정수와 같은 것이 존재하지 않으므로 (BigInt 제외) 주의해야 합니다.
CASE 1
console.log(3 / 2); // 1이 아닌, 1.5
console.log(Math.floor(3 / 2)); // 1
명백한 정수는 암묵적인 실수입니다.
CASE 2
0.1 + 0.2 = 0.30000000000000004
정수 값은 32 비트 정수로 처리되며 일부 구현은 32 비트 정수가 아닌 숫자에 유효한 명령어를 수행할 때까지 이러한 방식으로 저장합니다. 이는 비트 단위 작업에 중요할 수 있습니다.
덧셈, 뺄셈, 계수 (또는 나머지) 연산을 포함하는 표준 산술 연산자가 지원됩니다.
산술 연산자
연산자 | 설명 | 예제 |
나머지 연산자(%) | 이항 연산자로 두 피연산자를 나눈후 나머지를 반환 | 12 % 5 는 2를 반환합니다. |
증가 연산자(++) | 단항 연산자로 피연산자에 1을 더합니다. 만약 연산자를 피연산자 앞(++x)에 사용하면, 피연산자에 1을 더한 값을 반환. 연산자를 피 연산자 뒤(x++)에 사용하면, 피연산자에 1을 더하기 전 값을 반환 | x 가 3이면 ++x 는 x 를 4로 만들고 4를 반환합니다. 반면 x++ 는 3을 반환하고 x 를 4로 만듭니다. |
감소 연산자(--) | 단항 연산자로 피연산자로 부터 1을 뺍니다. 반환값은 증가 연산자와 유사합니다. | x 가 3이면 --x 는 x 를 2로 만들고2를 반환합니다. 반면 x-- 는 3을 반환하고 x 를 2로 만듭니다. |
단항 부정 연산자(-) | 단항 연산자 입니다. 피연산자의 반대값(부호 바뀐값)을 반환합니다. | x 가 3이면 -x 는 -3을 반환합니다. |
숫자화 연산자(+) | 단항연산자 입니다. 피연산자가 숫자값이 아니라면 피연산자를 숫자로 변환하기를 시도합니다. | +"3" 은 3을 반환합니다. +true 는 1. 을 반환합니다. |
고급 수학 함수와 상수를 다루기 위한 Math로 불리는 내장 객체가 있습니다.
Math.abs(x) 숫자의 절댓값을 반환합니다.
Math.acos(x) 숫자의 아크 코사인 값을 반환합니다.
Math.acosh(x) 숫자의 쌍곡 아크 코사인 값을 반환합니다.
Math.asin(x) 숫자의 아크 사인 값을 반환합니다.
Math.asinh(x) 숫자의 쌍곡 아크 사인 값을 반환합니다.
Math.atan(x) 숫자의 아크 탄젠트 값을 반환합니다.
Math.atanh(x) 숫자의 쌍곡아크 탄젠트 값을 반환합니다.
Math.atan2(x, y) 인수 몫의 아크탄젠트 값을 반환합니다.
Math.cbrt(x) 숫자의 세제곱근을 반환합니다.
Math.ceil(x) 인수보다 크거나 같은 수 중에서 가장 작은 정수를 반환합니다.
Math.clz32 주어진 32비트 정수의 선행 0 개수를 반환합니다.
Math.cos(x) 숫자의 코사인 값을 반환합니다.
Math.cosh(x) 숫자의 쌍곡 코사인 값을 반환합니다.
Math.exp(x) Ex를 반환합니다. x는 인수이며 E는 오일러 상수(2.718...) 또는 자연로그의 밑입니다.
Math.expm1(x) exp(x)에서 1을 뺀 값을 반환합니다.
Math.floor(x) 인수보다 작거나 같은 수 중에서 가장 큰 정수를 반환합니다.
Math.fround(x) 인수의 가장 가까운 단일 정밀도 표현을 반환합니다.
Math.hypot([x [, y [,...]]]) 인수의 제곱 합의 제곱근을 반환합니다.
Math.imul(x, y) 두 32비트 정수의 곱을 반환합니다.
Math.logg(x) 숫자의 자연로그(loge 또는 ln) 값을 반환합니다.
Math.log1p(x) 숫자 x에 대해 1 + x의 자연로그(loge 또는 ln) 값을 반환합니다.
Math.log10(x) 숫자의 밑이 10인 로그를 반환합니다.
Math.log2(x) 숫자의 밑이 2인 로그를 반환합니다.
Math.max([x [, y [,...]]]) 0개 이상의 인수에서 제일 큰 수를 반환합니다.
Math.min([x [, y [,...]]]) 0개 이상의 인수에서 제일 작은 수를 반환합니다.
Math.pow(x, y) x의 y 제곱을 반환합니다.
Math.random() 0과 1 사이의 난수를 반환합니다.
Math.round(x) 숫자에서 가장 가까운 정수를 반환합니다.
Math.sign(x) x의 양의 수인지 음의 수인지 나타내는 부호를 반환합니다.
Math.sin(x) 숫자의 사인 값을 반환합니다.
Math.sinh(x) 숫자의 쌍곡 사인 값을 반환합니다.
Math.sqrt(x) 숫자의 제곱근을 반환합니다.
Math.tan(x) 숫자의 탄젠트 값을 반환합니다.
Math.tanh(x) 숫자의 쌍곡 탄젠트 값을 반환합니다. Math.toSource() 문자열 "Math"를 반환합니다.
Math.trunc(x) 숫자의 정수 부분을 반환합니다.
내장 parseInt() 함수를 사용하여 문자열을 정수로 변환할 수 있습니다. 이는 다음과 같이 옵션으로 주어지는 두 번째 매개변수를 밑으로 하여 수행할 수 있습니다. 또한 8진수와 16진수의 문자열을 변숫값으로 지정해줄 경우 10진수 정수로 변환시켜 줍니다. 그러나 8진수는 신형 브라우저에서는 지원되지 않습니다.
문자열이 수가 아닌 경우 NaN ("Not a Number" (수가 아님)을 줄인 약자)로 불리는 특별한 값을 돌려줍니다.
parseInt('123', 10); // 123
parseInt('010', 10); // 10
parseInt('0x10'); // 16
parseInt('11', 2); // 3
parseInt('hello', 10); // NaN
이와 비슷하게 내장 함수 parseFloat()를 사용하여 부동 소수점 숫자를 파싱 할 수 있습니다. parseInt()와 달리 parseFloat()는 항상 10진수를 사용합니다.
매개변수로 주어진 값 분석하고 부동 소수점 수를 반환합니다. 기호(+, -), 숫자(0-9), 소수점 또는 지수 이외의 문자를 발견하면, 그 전까지의 결과만 반환하고 문제의 문자와 그 이후는 모두 무시합니다.
parseFloat(3.14); // 3.14
parseFloat('3.14'); // 3.14
parseFloat('314e-2'); // 3.14
parseFloat('0.0314E+2'); // 3.14
parseFloat('3.14와 숫자가 아닌 문자들'); // 3.14
NaN이 결과로 나왔을 경우 주의해야 할 점으로는 어떤 수학 연산의 입력값으로 주어지면 그 결과 역시 NaN이 된다는 점입니다.
NaN * 10 + 1; // NaN
내장 isNaN() 함수를 사용하면 NaN인지 여부를 검사할 수 있습니다.
isNaN(NaN); // true
javascript는 Infinity라는 무한대를 나타내는 전역 속성 숫자 값이 있습니다.
Infinity의 초기값은 Number.POSITIVE_INFINITY로 Infinity는 다른 어떤 수보다 더 큽니다.
console.log(Infinity); /* Infinity */
console.log(Infinity + 1); /* Infinity */
console.log(Math.pow(10,1000)); /* Infinity */
console.log(Math.log(0)); /* -Infinity */
console.log(1 / Infinity); /* 0 */
console.log(1 / 0); /* Infinity */
'Javascript' 카테고리의 다른 글
JavaScript 타입별 정리 Object (1) (0) | 2021.03.23 |
---|---|
JavaScript 타입별 정리 Null (0) | 2021.03.23 |
JavaScript 타입별 정리 Symbol (0) | 2021.03.23 |
JavaScript 타입별 정리 Boolean (0) | 2021.03.23 |
JavaScript 타입별 정리 Strings (0) | 2021.03.23 |
댓글