ES6 숫자(Number)
목차
프로그램을 만드는 것은 데이터를 조작하기 위해서 입니다. 데이터에는 여러가지 타입(type)이 있지만 가장 근본적인 데이터는 숫자(Number)라고 할 수 있습니다. 자바스크립트의 문자는 유니코드입니다. 유니코드도 결국은 숫자이기 때문에 숫자의 중요성은 아무리 강조해도 지나치지 않습니다.
자바스크리트는 동적 타입(dynamic typed) 언어로 다른 정적 타입(static typed) 언어처럼 바이트형, 부동소수점 형과 같이 저수준을 다루지는 않습니다. typeof 연산자로 정수나 소수를 체크해도 같은 number 형이 나옵니다. 그렇지만 코드를 작성하다 보면 소수 표기를 사용할 때도 있고 반올림을 해야하는 경우도 있습니다. 또 16진수나 2진수를 써야할 때도 있는데 이런 것들을 처리하기 위해 여러가지 내장 함수(메소드)들을 지원합니다.
이번 포스팅에서는 ES6의 숫자 타입에 대해 알아보겠습니다.
16진수, 8진수, 2진수
다음 예제는 16진수, 8진수, 2진수 표기를 사용합니다. 0x (16진수) 0o (8진수) 0b (2진수) 는 일반적인 표기법이니 파이썬 등 다른 언어의 소스코드에서도 볼 수 있을 것 입니다.
// Hexadecimal, ES5 console.log(0x0001); // --> 1 console.log(0x000F); // --> 15 // Octal, ES6 console.log(0o0001); // --> 1 console.log(0o0100); // --> 64 // Binary, ES6 console.log(0b0001); // --> 1 console.log(0b1111); // --> 15 // 10진수 -> 16, 2, 8진수 console.log(65535..toString(16)); // ffff console.log(15..toString(2)); // 1111 console.log(4095..toString(8)); // 7777 // .. 도트연산자가 두개인 것은 소수점과 혼동하지 않기 위함입니다.
컴퓨터에서 왜 16진수 8진수 2진수를 많이 쓰는가? 이유가 있습니다. 원초적인 저수준 레벨에서 보면 CPU는 0과1 밖에 이해하지 못하는 기계입니다. 0과1만 있고 0000 0001 이런식으로 수를 세는 체계입니다. 각 digit(숫자의 자리)을 손가락 하나로 생각해도 됩니다. 손가락을 접힌 것과 핀 것 이 두가지 상태로 수를 세고 계산을 합니다. 2개가 되면 진(위로 나아간다) 한다고 해서 2진법입니다.
8진법은 8개가 되면 나아가는 수입니다. 그런데 8은 2의 배수이며 3제곱입니다. 8을 2진법으로 쓰면 1000 입니다. 8진법에서 8은 10입니다. 2진법을 8진법으로 변환하는 것이 10진법으로 변환하는 것보다 자연스럽습니다. (리눅스의 파일 허가(file permision)는 8진수를 방식입니다)
16진법은 16개가 되면 한자리 나아가는 수입니다. 사람들은 10을 기준으로 하지만 그것은 그냥 사람의 기준입니다. 11을 표현하는 별도의 기호가 없기 때문에 알파벳 A~F를 붙였습니다. 즉 1,2,3 … 9, A, B, C, D, E, F (F가 15) 입니다. 이런 방식은 일관성이 있는데 예를 들어 20진수를 표현하려면 G, H, I, J 까지 해서 J를 19에 놓으면 20개가 되면 그 다음 자리수로 나갈 수 있습니다.
255를 16진수로 바꾸면 FF (15*16+15)이고 2진수로는 1111 1111 입니다. 역시 기계어인 2진수와의 호환성이 10진수 보다 좋습니다. 특히 컴퓨터 하드웨어인 메모리 주소를 16진수로 표기하는데 0과1의 상태를 가진 트랜지스터를 8개 묶은 1byte(8bit)가 최소단위로 1byte의 배수로 메모리 주소를 맵핑하기 때문입니다. 32비트(4byte) 64비트(8byte)란 것은 CPU레지스터의 차이를 말하지만 동시에 메모리의 주소 크기를 말합니다. 예를 들어 32비트 메모리 주소의 범위는 0x0000 0000 ~ 0xFFFF FFFF 처럼 깔끔하게 나옵니다. 2진수로 표시하면 32개의 0과 1 자리를 표기해야 하는데 4분의1인 8개의 digit 으로 표현이 됩니다. 10진수로 표시하면 0~4294967296 이렇게 나오는데 뭐 4기가라고 부르긴 합니다.
약간 깊은 이야기지만 다양한 진법을 사용하려면 컴퓨터의 원리를 좀 더 알고 있으면 좋습니다.
Integer 관련 메소드
숫자를 크게 나누면 정수와 실수입니다. 컴퓨터에서는 무한소수의 규칙이나 개념을 표현할 수는 있지만 그 값들을 모두 저장하는 것은 불가능합니다. 정수도 마찬가지로 최대값과 최소값의 제한이 있습니다. Number.MAX_SAFE_INTEGER 같은 메소드로 확인할 수 있습니다.
// checking if num is an integer console.log(Number.isInteger(7)); // --> true console.log(Number.isInteger(-5)); // --> true console.log(Number.isInteger(1.99)); // --> false // MIN MAX SAFE INTEGER console.log(Number.MAX_SAFE_INTEGER); // long positive number console.log(Number.MIN_SAFE_INTEGER); // long negative number console.log(Number.isSafeInteger(100000000000)); // true console.log(Number.isSafeInteger(10000000000000000000)); // false
Number.isNaN
기존의 isNaN 함수보다 none number 타입 검사를 강화한 Number.isNaN입니다. 이름이 Not a Number라서 혼동을 주는데 NaN의 타입은 number 이고 값이 NaN 입니다. 그러니까 number 가 아니다 – 라는 생각에 사로잡히면 이해에 어려움이 있습니다. NaN 값은 다음과 같이 만들 수 있습니다. number 타입이지만 숫자 연산이 안되는 값 입니다.
>undefined*10 NaN >'TEXT'*10 NaN
NaN의 특징은 NaN === NaN 의 결과가 false 입니다. 왜냐하면 undefined*10 === undefined*10 처럼 같을 수가 없기 때문입니다.
>NaN === NaN false >NaN !== NaN true
기존의 isNaN은 매개변수를 Number() 함수로 변환한 후에 비교하기 때문에 허점이 있습니다. ‘NaN’이 NaN과 같다는 평가를 합니다. NaN !== NaN 이 됩니다. Number.isNaN은 ‘NaN’ !== ‘NaN’ 으로 false를 반환합니다.
*기존 isNaN >isNaN(NaN) true >isNaN('NaN') true *Number.isNaN >Number.isNaN(NaN) true >Number.isNaN('NaN') false
ECMAScript2015(ES6)에 따르면 1. number 타입이 아니면 false 2. number가 NaN이면 true 3. 그외의 경우 false 리턴이라고 명시합니다. isNaN과의 주요 차이점은 Number() 변환 여부입니다.
아래 예제를 보면 똑같은 ‘TEXT’에 대해서도 차이점을 보이는데요. ‘TEXT’가 Not a Number – 숫자가 아니라는 의미로 보면 isNaN이 맞지만 Number.isNaN은 오히려 false인 것이 type 이 string 이라 ES6 명세에 따르면 false가 맞습니다. 실제로 typeof NaN을 보면 number 타입으로 isNaN은 정확하지 않거나 모호한 결과입니다. 결론적으로 ES6기준은 Number.isNaN의 사용을 권장하고 있습니다. 정확한 NaN 값을 평가하도록 합니다.
>isNaN('TEXT') true >Number.isNaN('TEXT') false
NaN이 혼동이 된다면 자바스트립트 비교연산자에 대한 참고가 도움이 될 수 있습니다. ==, ===, !=, === 들을 정확하게 이해하도록 합니다.
Math 함수
ES6의 몇가지 Math 함수를 알아보겠습니다.
sign은 부호를 추출하고 trun는 소수점을 잘라냅니다. log는 수학의 log 함수입니다.
hypot은 피타고라스 공식으로 두변의 길이로 나머지 한변의 길이를 구합니다.
// sign console.log(Math.sign(-1)); // -1 console.log(Math.sign(0)); // 0 console.log(Math.sign(+1)); // 1 // trunc console.log(Math.trunc(2.1)); // 2 console.log(Math.trunc(-2.1)); // -2 console.log(Math.trunc(3.34)); // 3 console.log(Math.trunc(-3.34)); // -3 // log console.log(Math.log10(100)); console.log(Math.log2(16)); // 자연로그 console.log(Math.log1p(10)); // 피타고라스 긴 변의 길이 console.log(Math.hypot(3,4));
요약
숫자와 데이터형은 프로그래밍을 하면서 좀 지루할 수 있는 부분입니다. 하지만 가장 기초기 때문에 소홀히 하면 뒤로 갈수록 어려움이 있습니다. 자바스크립트는 웹브라우저의 콘솔창으로 충분히 실습을 하는 것이 도움이 될 것 입니다. 계산기를 가지고 논다(?)는 생각으로 하다보면 빠른 시간에 많은 것을 익힐 수 있습니다.
참고링크
https://262.ecma-international.org/6.0/#sec-number.isnan