함정 시리즈

[JavaScript] 0과 -0 (JavaScript 정수 자료형의 함정)

노새두마리 2023. 11. 9. 16:17

 

정수 자료형? 그런 건 따로 없소이다. 모든 것은 숫자(Number)로 통합니다.

 

-0 만들기

작업에 큰 지장은 없지만 직접 마주한다면 은근히 거슬리는 -0이라는 녀석, 이 녀석은 어떻게 생길까요?

  • 직접 -0을 입력
  • 부호가 마이너스이면서 곱셈의 결과가 0이 되도록 하기
-0;
-1 * 0;
1 * -0;
0 * -0;

-0을 마주하게 된 배경

구현한 자료구조가 제대로 동작하는지 확인하기 위해 정수 범위에 걸친 랜덤한 데이터가 필요했습니다.

데이터를 만들기 위해 아래와 같은 로직을 통해 임의의 수를 생성하였습니다. (반복문 생략)

const N = 100; // 숫자 범위 조정
(Math.round(Math.random())) * 2 - 1) * Math.floor(Math.random() * N);

// -99 이상 99 이하의 임의의 값 생성

 

// 부호를 결정하는 부분
Math.round(Math.random()); // 0 또는 1
Math.round(Math.random()) * 2; // 0 또는 2
Math.round(Math.random()) * 2 - 1; // -1 또는 1

// 숫자를 결정하는 부분
Math.floor(Math.random() * N); // 0 이상 N 미만의 자연수

이 과정에서 부호로써 -1, 값으로써 0이 추출되어 조합되면 -0이라는 기괴한 녀석이 데이터에 추가되었습니다.


-0의 존재에 대한 의심

0의 음수를 2의 보수로 표현하면 결국 0을 표현하는 비트와 동일해지기 때문에 0과 -0은 같습니다. 따라서, -0을 저장하고자 했더라도 이를 불러왔을 때에는 0이어야 하며, -0을 저장하려 했다는 사실을 기억할 수 없어야만 할 것 같습니다. 하지만, 이는 정수 자료형을 사용하고 있다는 전제가 있어야 성립할 수 있습니다.

2의 보수란? https://ko.wikipedia.org/wiki/2%EC%9D%98_%EB%B3%B4%EC%88%98


하지만 JavaScript는 정수 자료형이 없다.

-0이 의미하는 바, 그리고 제가 놓치고 있던 사실은 다음과 같습니다.

JavaScript는 모든 숫자를 Number 자료형 하나로 표현하며, 부동소수점 방식을 사용한다.

0과 -0을 정수 비트로 표현하면 동일하게 0이 되지만, 부호, 지수부, 가수부로 나뉘는 부동소수점 방식으로 표현했다면 이야기가 달라집니다.

0을 나타내는 비트에서 부호 비트만 1로 바꾸면 음수임을 표현할 수 있으므로 -0을 표현할 수 있게 됩니다.

부동소수점 표현 방식? https://ko.wikipedia.org/wiki/IEEE_754


-0의 쓸모

그럼 이 -0은 어디에다가 사용할 수 있죠?

1/0; // Infinity;
1/-0; // -Infinity;

저는 나중에 사용하더라도 이 정도만 활용할 수 있을 것 같습니다.


-0을 신경써서 작업해야 하는가?

-0은 덧셈, 곱셈 등 대부분의 산술 연산에 있어서 0 의 역할을 수행할 수 있습니다. 또한, 사용자 화면에 표시해야 하는 경우에는 문자열로 변환하는 과정에서 0으로 바뀝니다. 따라서, 대부분의 경우에는 이를 무시하고 사용할 수 있습니다.

-0 * 100; // -0이기는 하나 실제 변환이 필요한 곳에 표시될 때에는 0으로 바뀔 가능성 높음
-0 + 7; // 7
(-0).toString(); // '0'

 


정리

  • JavaScript에는 정수 자료형이 따로 존재하지 않는다.
  • 모든 숫자는 Number 자료형 하나로 표현되며, 부동소수점 표현 방식을 사용한다.
  • 대부분의 -0은 연산에 있어서 0과 거의 일치하게 동작하며, 문자열로의 형변환 등을 거치면 0으로 변환되므로 크게 신경쓰지 않아도 괜찮다.