2.4.3 특수 숫자

jude·2022년 1월 31일
0

you don't know js

목록 보기
16/30
post-thumbnail

1. NaN(Not a Number)

NaN은 말 그대로 '숫자 아님'이다. 하지만 사실 '유효하지 않은 숫자'라고 하는게 더 적절하다.

var a = 2 / "foo"; // NaN

typeof a === "number"; // true

Not a Number 즉, 숫자가 아닌데 타입이 "number"라니 이 무슨 해괴한 말인가?

var a = 2 / "foo";

a == NaN; // false
a === NaN; // false
NaN === NaN; // false

NaN은 유일하게 자기 자신과 비교를 해도 동등하지 않다.

그래서 NaN을 판별할 수 있는 전역 유틸리티가 있는데 window.isNaN() 이다.
그런데 문제는 말 그대로 '숫자가 아닌지' 만 판단한다.

var a = 2 / "foo";
var b = "foo";

a; // NaN
b; // "foo"

window.isNaN( a ); // true
window.isNaN( b ); // true - ???

b는 숫자가 아니더라도 NaN은 아닌데 이렇게 되면 제대로 된 NaN을 판별할 수가 없다.

ES6부터는 Number.isNaN() 이 생겼다.

ES6이하 브라우저에서는 폴리필을 사용하면 된다.

if (!Number.isNaN) {
  Number.isNaN = function (n) {
    return (
      typeof n === "number" &&
      window.isNaN( n )
    );
  }
}

var a = 2 / "foo";
var b = "foo";

Number.isNaN( a ); // true
Number.isNaN( b ); // false

자기 자신과 비교시 유일하게 다른 값이기 때문에 더 간단히 폴리필을 만들 수도 있다.

if (!Number.isNaN) {
  Number.isNaN = function (n) {
    return n !== n;
  };
}

2. 무한대

자바스크립트에서 무한대를 나타내는 값은 양의 무한대 Infinity와 음의 무한대 -Infinity가 있다.

var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity

Number.POSITIVE_INFINITY === Infinity; // true
Number.NEGATIVE_INFINITY === -Infinity; // true

Infinity / Infinity; // NaN

무한대를 무한대로 나누면 1이라고 생각할 수 있지만, '무한대' 라는 말 자체가 그 값을 알 수 없이 큰 값이라는 뜻이기 때문에,
무슨 수에서 얼만큼 나눌지 알아야 정확히 똑같이 나눌거 아닌가?
그래서 1이 아닌 NaN(Not a Number가 아닌 유효하지 않은 숫자로 생각하자..)이 반환된다.

아무 양수를 무한대로 나누면? 0
아무 음수를 무한대로 나누면? 0일까?

10 / Infinity; 0
-10 / Infinity; -0

-0 이란 숫자가 나온다.

3. 영(0)

혼란스럽다. 0은 알겠는데 -0은 대체 왜 존재하는 것인가?

var a = 0 / -3; // -0
var b = 0 * -3; // -0

덧셈과 뺄셈에서는 -0이 나올일이 없다.

IE는 버전에 상관없이 0 이 나온다..;


문자열 / 숫자화 시킬 때 주의

-0문자열화 시키면 0이 된다.

var a = 0 / -3;

a // -0

a.toString() // 0
a + "" // 0
String( a ) // 0
JSON.stringify( a ) // 0

그런데 반대로 문자열 -0에서 숫자화 시키면 그대로 -0 이다.

+"-0"; // -0
Number( "-0" ); // -0
JSON.parse( "-0" ); // -0

-0을 비교 연산할 때도 특이하다.
연산자 사용시 무조건 0과 -0은 같다 라는 결과가 나온다.

var a = 0;
var b = 0 / -3;

a == b; // true
-0 == 0; // true

a === b; // true
-0 === 0; // true

0 > -0; // false
a > b; // false

0과 -0을 판별하려면 아래와 같은 함수로 판별 가능하다.

function isNegZero(n) {
  n = Number( n );
  return (n === 0) && (1 / n === -Infinity);
}
isNegZero( -0 ); // true
isNegZero( 0 / -3 ); // true
isNegZero( 0 ); // false

-0을 만든 이유
값의 크기로 어떤 정보(예: 애니메이션 프레임당 넘김 속도)와 그 값의 부호로 또 다른 정보(예: 넘김 방향)를 동시에 나타내야 하는 애플리케이션이 있기 때문이다.

어떤 변숫값이 0에 도달하여 부호가 바뀌는 순간, 그 직전까지 이 변수의 이동 방향은 무엇인지 알 수가 없으므로 부호가 다른 두 0은 유용하다.
즉, 잠재적인 정보 소실을 막기 위한 것.

profile
UI 화면 만드는걸 좋아하는 UI개발자입니다. 프론트엔드 개발 공부 중입니다. 공부한 부분을 블로그로 간략히 정리하는 편입니다.

0개의 댓글