자바스크립트의 Number 데이터 타입
ECMAScript 에서 Number 자료형은 정수형(Integer Value)이든 소수형(Floating Point Value)이든 상관없이 IEEE-754 형식을 이용해서 저장한다. IEEE-754가 뭔지 잠시 짚고 넘어가자면IEEE-754는 전기 전자 기술자 협회(IEEE)에서 개발한 컴퓨터에서 부동소수점를 표현하는 가장 널리 쓰이는 표준이다. ±0 등의 수와 무한, NaN 등의 기호를 표시하는 법과 이러한 수에 대한 연산을 정의하고 있다.
간단히 말하자면 0 과 1, 즉 이진법으로 이루어진 컴퓨터 연산체계에서 0 과 1 이상의 수들을 표현하는 표준 방식이라고 할 수 있다. IEEE-754 체계에서는 가장 첫번째 비트가 +,-인지를, 즉 그 수가 음수인지 양수인지를 나타내는데, 이러한 이유로 ECMAScript 에서는 0과 -0이 둘다 존재할 수 있다. 물론 0 == -0이라는 조건은 true(참)이다.
정수형
IEEE 32bits Single Precision 형식 |
ECMAScript 는 굉장한 유연성과 높은 자유도를 가졌는데, 이러한 이유로 다양한 정수형 수들(8진수, 16진수)을 표현하기위한 다양한 문법들이 존재한다.
참고로 정수형 수들을 저장할 때는 32bits single precision 형식으로 저장된다는걸 기억하자. 즉 어떤 정수 값이든간에, 32비트 형식으로 저장된다는 것 이다. 위의 그림에 나와있는 방식으로 저장된다 생각하면 된다.
var integerNumber = 35; //integer 값을 선언할 때
//8진수를 표현할 때는 첫번째 자리의 숫자가 무조건 0 이여야 한다.
var octalNumber1 = 07; //8진수 07, 10진수로 환산하면 7
var octalNumber2 = 017; //8진수 017, 10진수로 환산하면 15
var octalNumber3 = 019; //3번째 자리의 수가 8진수에 없는 숫자인 9라 일반 10진수로 받들여지게 된다.
//하지만 8진수의 사용은, strict 모드에서 에러를 발생시키고, 몇몇 브라우져에서는 제대로 실행되지 않으므로 사용을 자제하자.
//16진수를 표현할 때에는 숫자 앞에 무조건 0x 를 붙인다.
var hexaNumber1 = 0x7; //16진수 07, 10진수로 환산하면 7
var hexaNumber2 = 0xA7; //16진수 A7, 10진수로 환산하면 167
var hexaNumber3 = 0xB35; //16진수 B35, 10진수로 환산하면 2869
하지만 결국 16진수나 8진수로 선언된 변수들도 연산시에는 다 10진수로 변환되니, 별다른 특별한 이유가 없으면 10진수를 사용하도록 하자.
소수형
IEEE 64bits Double Precision 형식 |
ECAMScript에서의 소수형은 정수형과는 달리 64bits double precision 형식으로 저장된다. 바로 위의 그림과 같은 형식이다. 소수형 수들은 아래와 같이 선언되는데
var floatingNumber1 = 0.3;
var floatingNumber2 = 1.47;
var floatingNumber3 = .7;//안 좋은 예제 1
var floatingNumber3 = 3.;//안 좋은 예제 2, 결국 3으로 자동 변환되 저장됨
var floatingNumber3 = 4.0;//안 좋은 예제 3, 4가 정수형으로 인식되서 32bit 형식으로 저장됨
var floatingNumber3 = 4.572e3;// = 4572, 많이 작거나 큰 숫자의 경우에는 e-notation을 이용 10의 몇 승으로 표현할 수 있다.
var floatingNumber3 = 4.572e-3;// = 0.04572
//ECMASCript 는 소수점아래로 0이 5개보다 많을 시에 무조건 e-notation을 이용한 표기법으로 수를 표현한다.
var testFloat = 0.0000006533;
console.log(testFloat); //6.533e-7
위와 같이 다양한 방식으로 선언되고 어싸인될 수 있는데, 몇가지 피해야할 방식들이 있다. ECMAScript에서 정수형은 32bits로 소수형은 64bits 로 표현되는 만큼, 소수형을 표현하는데는 정수형의 2배에 달하는 메모리를 사용해야 한다. 이러한 이유로 ECMAScript는 제대로된 형식이 아닌 소수형 수들은 무조건 integer로 인식 32bits 형식으로 저장하게 된다.
우선 안 좋은 예제 1은 작동은 하나, 최대한 피해야할 방법이다. 몇몇 Javascript 엔진에 따라서는 에러가 뜰 수도, 또는 0이나 1로 변환되서 저장될 수도 있다.
안 좋은 예제 2 같은 경우는 제대로 완성되지 않은 숫자라, 3으로 자동 변환되서 저장된다.
안 좋은 예제 3 같은 경우에는 숫자 4.0가 정수형으로 변환되서 32bit 형식으로 저장된다.
소수형을 이용한 연산을 할 때 조심해야할건, 무슨 일이 있어도 var1 + var2 = 0.6 같은 소수형 비교는 하면 안된다는건데, 이 이유는 IEEE-754의 정확성에 있다.
IEEE-754 방식은 그냥 일반 수를 표현할 때는 소수점 아래로 17번째 자릿수까지 완벽하게 정확하지만, 사칙연산시에 그 결과값의 정확성이 매우 떨어지기 때문이다.
var var1= 0.2; //Double Precision시에 0.20000000298023224라는 값으로 저장된다.
var var2= 0.4; //Double Precision시에 0.4000000059604645라는 값으로 저장된다.
console.log(var1 + var2 == 0.6); //false값이 프린트된다
var var3= 0.6; //Double Precision시에 0.6000000238418579라는 값으로 저장된다.
console.log(var1 + var2 == var3); //false값이 프린트된다
위와 같은 경우
var1 + var2 는 0.6000000089406967라는 결과를 도출하게되고, 0.6이라는 값(메모리내에는 0.6000000238418579라는 값으로 저장) 과 일치하나는 조건에서 false(거짓)값을 가지게 된다.
그러니 소수형 수의 연산값을 이용한 조건문은 절대로 쓰지 않도록 하자.
표현할 수 있는 수의 범위와 무한(Infinity) 값
ECMAScript에서 Number 자료형을 표현할 때 사용하는 비트수에 제한이 있다보니, 표현할 수 있는 수가 무한하지가 않다.
최대로 표현가능한 수와 최소수는 아래와 같이 확인이 가능하다.
console.log(Number.MAX_VALUE); //양수의 최대값
console.log(Number.MIN_VALUE); //양수의 최소값
만약 이에서 더 커지거나 작아지면 IEEE-754로 표현하는 한계를 넘으면 그 수는 Infinity 로 표현된다
console.log(Number.MAX_VALUE + Number.MAX_VALUE); //Infinity
console.log(- Number.MAX_VALUE - Number.MAX_VALUE); //-Infinity
그리고 Infinity 값은 Infinity를 제외한 다른 수와의 어떤 연산에서도 Infinity 값을 결과로 도출한다.
참고로 Infinity 값은 아래와 같이 불러올 수 있다.
console.log(Number.NEGATIVE_INFINITY + Number.POSITIVE_INFINITY); //NaN
console.log(Number.NEGATIVE_INFINITY + Number.MAX_VALUE); //-Infinity
console.log(Number.POSITIVE_INFINITY - Number.MAX_VALUE); //Infinity
NaN 값 이란?
간단하다. Not a Number 의 약자로 연산의 결과가 수가 아닐때 사용된다.
-Infinity + Infinity, 3/0 와 같이 결과가 숫자로 도출될 수 없을 떄 사용된다.
console.log(Number.NEGATIVE_INFINITY + Number.POSITIVE_INFINITY); //NaN
console.log(NaN + 3);//NaN이 포함된 연산은 언제나 결과가 NaN이다.
console.log(NaN == NaN); //false
//NaN값은 본인을 포함한 어떠한 값과도 Equal하지 않는다. 이러한 이유로 ECMAScript 에는 isNaN이라는 function이 있다
console.log(isNaN(NaN)); //true
이 isNaN() function 은 주어진 파라미터를 Number 자료형으로 변환 시도를 해서, 성공적으로 변환이 되면 false 를 아니라면 true 값을 리턴하는 함수이다.
그러니 ECMAScript 의 자동변환으로 Number 자료형으로 변환될 수 있는 경우에는 false 값이 리턴된다.
console.log(isNaN(NaN)); //true
console.log(isNaN(1)); //false
console.log(isNaN("1")); //false
console.log(isNaN("test")); //true
console.log(isNaN(true)); //false
타 자료형을 Number 자료형으로 변환시
자바스크립트(ECMAScript)는 Number(), parseInt(), parseFloat() 함수등을 이용해 타 자료형을 Number 자료형으로 변환 할 수가 있다. 변환 값은 아래 표를 참고하자
Number() 함수를 사용해 타 자료형을 변환시
var num1 = Number("String");
var num2 = Number(true);
var num3 = Number(null);
var num4 = Number(undefined);
var num5 = Number(NaN);
var num6 = Number(new Object());
자료형
| 변환시 Number 값 | |||
0 | 1 | NaN | 숫자 | |
Boolean | false | true | 해당 사항 없음 | 해당 사항 없음 |
Undefined | 해당 사항 없음 | 해당 사항 없음 | undefined | 해당 사항 없음 |
Null | null | 해당 사항 없음 | 해당 사항 없음 | 해당 사항 없음 |
Number | 0 | 1 | NaN | 모든 숫자들 |
String | "0" or "" | "1","01" | "TEST", "0Tx34",등 다른 조건에 부합하지 않을 때 | 따옴표 사이에 숫자밖에 없을 때 자동으로 수로 변환(16진수도 10진수로) |
Object | 해당 사항 없음 | 해당 사항 없음 | 모든 object 타입 | 해당 사항 없음 |
String 자료형의 Number 자료형으로의 변환에 대해 짧게 설명하자면,
"0", "11", "055" 와 같이 스트링의 따옴표 사이에 숫자 밖에 없다면, 무조건 동일한 Number 값으로 변형된다. 숫자의 맨 앞에오는 0은 생략되고, 만약 따옴표안에 "0xAB"와 같이 16진수 수가 있다면 자동으로 10진수로 변환된다.
Empty String, 빈 스트링 값 같은 경우에는 무조건 0으로 변환되고, 이를 제외한 모든 상횡에서는 다 NaN값으로 변환된다.
parseInt() 함수를 사용해 타 자료형을 변환시
parseInt() 함수는 Number 함수와 String 자료형 변환을 제외하고는 모두 똑같은 변환값을 가진다. 하지만 String 값의 경우에 캐릭터가 들어간 모든 String을 NaN 값 으로 변환하는 Number와 달리 첫자리가 숫자라면, 이어지는 숫자들까지 모두 Number 자료형(정수)으로 변환한다. 또한, 파라미터에 radix 를 설정해줄 경우에, 주어진 스트링을 2진수, 8진수, 16진수, 10진수로 인식하는것을 설정할 수도 있다
var num1 = parseInt("String");
var num1 = parseInt(true);
var num2 = parseInt(null);
var num3 = parseInt(undefined);
var num4 = parseInt(NaN);
var num5 = parseInt(new Object());
var num6 = parseInt("1110",2); //1110을 2진수로 인식, 10진수 14로 변환한다
var num7 = parseInt("17",8); //17을 8진수로 인식, 10진수 15로 변환한다
var num8 = parseInt("A3",16); //A3을 16진수로 인식, 10진수 163으로 변환한다
var num9 = parseInt("333",10); //10진수로 인식한다
자료형
| 변환시 Number 값 | |||
0 | 1 | NaN | 기타 | |
Boolean | false | true | 해당 사항 없음 | 해당 사항 없음 |
Undefined | 해당 사항 없음 | 해당 사항 없음 | undefined | 해당 사항 없음 |
Null | null | 해당 사항 없음 | 해당 사항 없음 | 해당 사항 없음 |
Number | 0 | 1 | NaN | 모든 숫자들,(소수일때 정수자리만 변환) |
String | "0" or "" | "1","01" | "TEST", "Tx34",등 다른 조건에 부합하지 않을 때 | 앞자리들이 숫자일 때는 앞자리들을 수로 변환("43TX8" -> 43) 만약 16진수라면 10진수로 변환("0xApp" -> 10) |
Object | 해당 사항 없음 | 해당 사항 없음 | 모든 object 타입 | 해당 사항 없음 |
parseFloat() 함수를 이용해 타 자료형을 변환시
parseFloat() 함수는 parseInt() 함수와 모든게 같으나, 32bits 정수형으로 변환하는 parseInt()함수와 달리 String 자료형 변환에서 소수형 수를 발견할 때 64bits 소수형으로 변환한다. 만약 정수형수라면 32bits 정수형으로 변환var num1 = parseInt("String");
var num1 = parseFloat("0.44TQG"); //0.44
var num2 = parseInt("32BB"); //32(O), 32.0(X)
댓글 없음:
댓글 쓰기