본문 바로가기
Archive

자바스크립트에서 숫자

by livemehere 2022. 8. 29.

다른언어와는 다르게 자바스크립트나 타입스크립트는 숫자에 관대하다고 느낀다.

int, double, float 이런 형식들이 number 하나로 통합되어 사용된다.

정확히는 number 와 bigint 두가지가 있다.

 

숫자를 입력할때 0 이라는 숫자는 정말 많이 쓰인다.

10억을 입력할때 0을 일일이 다 적지 않고, 생략할수 있는 기법을 제공하는데 'e' 를 활용하는 방법이있다.

const n = 3e20;
console.log(n); //300000000000000000000

e는 왼쪽 숫에 e 오른쪽 수만큼의 10의 거듭 제곱을 하는 효과이다.

동일하게 음수는 거듭제곱만큼 나누는 효과가 있다.

 

10진수, 16진수, 8진수 2진수

자바스크립트에서 지원하는 진법은 10진수를 포함해 4개이다.

다양한 진법을 숫자로 나타낼 수 있고 비교연산자는 값자체를 비교하기 때문에 같은 수를 나타낸다면 true이다.

const sib = 15;
const pal = 0o15;
const lee = 0b1101;
const yuc = 0xffff;

console.log(sib); // 15
console.log(pal); //13
console.log(lee); //13
console.log(yuc); //65535

 

number.toString(base) 를 사용하여 base진법으로 변환한 후 문자형으로 반환한다.

const n = 255;

console.log(n.toString(10));
console.log(n.toString(8));
console.log(n.toString(2));
console.log(n.toString(16));

base는 2 - 36 까지 지원하며, 기본값은 10이다.

 

보통 base에 따라서 표현하고자하는 값들이 있는데

16 : 색, 문자인코딩

2 : 비트연산

36 : 0-9 와 A-Z 를 사용해 숫자를 표현한다. 알파뱃 전체가 숫자를 표현하는데 사용되며 url을 줄이는 것과 같이 숫자로 된 긴 식별자를 짧게 줄일 때 사용된다.

 

숫자에서 바로 toString()

아래와 같이 이용해야한다. 숫자에는 소숫점 부분이있기 때문에, 점을 2개 연속해서 사용하거나, 괄호를 이용해 소숫점 부분까지 표현을 끝냈음을 알려야한다.

console.log((11).toString());
console.log(11..toString());

toFixed()

특정 소숫점까지 숫자를 구해 문자열로 반환해준다.

반올림을 적용한다.

 

혹은 곱셈과 나눗셈을 이용해서 구할 수 도있다.

let num = 12.37;
console.log(num.toFixed(1)); // "12.4"

console.log((num * 100) / 100); // "12.37"

정밀도 손실( loss of precision )

이건 정말 흥미로운 사실인데, 숫자는 내부적으로 64비트형식으로 표현된다.

그래서 숫자를 정확하게 표현하기 위해서는 52비트(숫자) + 11비트(소숫점위치) + 1비트(부호) 로 사용된다.

그런데 52비트를 초과하는 숫자를 표현하면 공간이 넘쳐버리고 Infinity로 처리된다.

console.log( 1e500 ); // Infinity

 

위처럼 강제로 숫자를 늘리면 표현의 한계를 넘어 Infinity로 처리되지만

 

연산을 통해서 발생한 숫자(IEEE-754) 는 가능한 가장 가까운 숫자를 반올림하는 방법을 통해 이문제를 해결한다 ( 숫자가 Infinity 로표현되는것을 막음)

그 결과 0.1 + 0.2 가 0.3이 되지 못한다.

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

 

왜일까?

 

소숫점을 표현하는것은 10의 거듭제곱을 표현하는 것이다.

즉, 10진수에서는 10의 거듭제곱을 정확하게 나타낼  수 있지만,

이 숫자들은 비트로 표현되기 때문에, 정확하게 표현할 수 없다.

0.1 은 이진수로 0.00011001100110011... 이다. 즉 정확히 표현할 수 없는 숫자이기 때문에,

0.2 조차 정확히 표현이 될 수 없고, 반올름을 하면 정확히 0.3이 되지 못한다.

 

직접 반올림을 해보면 아래와 같이 나온다.

console.log((0.1).toFixed(50)); // 0.10000000000000000555111512312578270211815834045410

 

이런현상은 js뿐만아니라 php, java, c 등의 다른 언어에서도 똑같은 결과를 얻는다. (아닌것도 있을 수 있음)

 

그래서 아래와 같은 결과도있다.

console.log(9999999999999999); // 10000000000000000

 

약간 우회해서 원하는 값을 얻기 위해서는 여러 방법이 있는데

let sum = 0.1 + 0.2;
alert( +sum.toFixed(2) ); // 0.3

자동으로 가까운 수에서 반올림 하기 이전에, 직접하는 수가 있다.

 

0, -0

자바스크립트에서는 0에도 부호를 붙일 수 있다.

하지만 연산에서는 동일하게 취급해서, 그냥 그렇다는 사실만 알면된다.

console.log(-0);

 

isNaN, isFinite

두가지는 NaN과 Infinity -Infinity 를 구분하기 위한 용도로 제공되는 함수이다.

아래와 같이 활용할 수 있다.

alert( isNaN(NaN) ); // true
alert( isNaN("str") ); // true

그냥 NaN === NaN 으로 사용하면 되지 않을까 싶지만,

NaN은 어떤 것과 비교해도 false를 반환하는 특징이있어서 안된다.

 

isFinite는 숫자의 표현중 정상적인 숫자를 찾아내는데 사용된다.

NaN, Infinity, -Infinity 일경우 false를 반환한다.

alert( isFinite("15") ); // true
alert( isFinite("str") ); // false, NaN이기 때문입니다.
alert( isFinite(Infinity) ); // false, Infinity이기 때문입니다.

parseInt, parseFloat

문자열을 숫자로 변경할 때 사용된다.

Number +의 단항연산으로 변환하는 것과의 차이점은, Number은 반드시 숫자형 문자만 있어야 변환이 되고, 아닌경우 에러를 반환하지만

이 두가지는 유효한 숫자문자열을 읽어들이고, 아닌경우 거기서 범추고 읽어들인 값까지만 숫자로 반환한다.

하지만 처음부터 문자열이 등장한다면 바로 멈춘다.

alert( +"100px" ); // NaN
alert( parseInt('100px') ); // 100
alert( parseInt('a123') ); // NaN, a는 숫자가 아니므로 숫자를 읽는 게 중지됩니다.

 

또 두번재 인수가 있는데, 원하는 진수를 지정해 줄 수도있다.

let a = "0xff";
console.log(parseInt(a, 16)); // 255

 

 

 

반응형

'Archive' 카테고리의 다른 글

자바스크립트 배열과 객체  (0) 2022.08.30
자바스크립트 문자열  (0) 2022.08.29
원시값의 메서드  (0) 2022.08.29
new 연산자와 생성자 함수  (0) 2022.08.29
객체  (0) 2022.08.29