JavaScript

[JavaScript] 비트 NOT 연산자 Tilde(~)와 "~~" 활용법

didue 2023. 11. 21. 09:54
반응형

 

 

비트 NOT연산자(~)

비트 NOT연산자 (~)는 피연산자의 비트를 반전시키는 연산자이며,

한글로 물결표라고 부르듯 Tilde(~,틸드) 연산자라고도 부른다.

 

 

피연산자는 32비트 정수로 변환되며 일련의 비트(0과 1)로 표현한다. 32비트를 넘어가는 숫자는 최상위 비트를 기준으로 삭제하며, 다른 비트 연산자와 마찬가지로 피연산자를 32비트 정수로 반환한다.

 

32비트 정수 피연산자는 2의 보수에 따라서 반전된다. 즉 최상위 비트는 음수를 표현하는데 사용한다.

 9 (base 10) = 0000 0000 0000 0000 0000 0000 0000 1001 (base 2)
               --------------------------------
~9 (base 10) = 1111 1111 1111 1111 1111 1111 1111 0110 (base 2) = -10 (base 10)

 

어떤 수 x에 대해 NOT 비트 연산을 하면 -(x+1)의 결과를 도출한다. 예를들면 ~-5의 결과는 4로 계산된다.

 

 

 

연산자 활용법

표현식 앞에 틸트 연산자를 사용하면 indexOf()의 직접 반환되는 숫자 인덱스 대신 참/거짓 으로 반환한다.

 

//normal code
if(sentence.indexOf(words) >= 0) {
}

예를 들어 sentence에 wrods가 있을때 indexOf()의 예상 결과는 양의 정수 또는 때로는 0이다.
이 예시를 tilde(~) 연산자를 사용하여 표현하면 아래와 같다.

 

//using tilde operator
if(~sentence.indexOf(words)) {
}

indexOf() 함수의 존재값이 없을 경우 -1을 반환하는데 -1은 2진수로 11111111로 표현한다.

여기에 tilde(~)연산자를 써서 반전시키면 00000000 즉, 0이 된다.

0은 false로 취급되는 falsy value이기 때문에 ~-1 === 0이라는 점을 이용해서 조건식을 간결하게 만들 수 있다.

 

 

이 외에도 자바스크립트에서는 -1을 반환하는 메소드들이 여럿 있다.

  • String.prototype.indexOf()
  • String.prototype.charAt()
  • String.prototype.search()
  • Array.prototype.indexOf()
  • Array.prototype.findIndex()

 

위와 같은 메소드들은 주로 탐색 메소드로써 타겟의 인덱스를 반환하는데, 타겟이 존재하지 않을 경우 -1을 반환한다. 이 점을 이용하여 tilde(~)연산자를 적용하여 활용해볼 수 있겠다.😋

 

 

 

~~ (double tilde)

기본적으로 tilde연산자는 소수점 아래의 비트를 버리는 성질을 가진다.

console.log(~1.1);      //-2
console.log(~1);        //-2

 

 

NOT연산은 기본적으로 두번 사용하면 "부정+부정=긍정"은 국룰이므로 원본값을 가진다.

console.log(!true);     //false
console.log(!!true);    //true

 

 

논리부정연산인 !은 단순히 true와 false를 역전시키지만, 비트논리연산자인 ~는 조금 다르다.

//ES6에서 추가된 Math.trunc를 바벨이나 Polyfill을 쓰지 않아도 된다.
console.log(Math.trunc(45.6)); // 45
console.log(~~45.6); // 45
console.log(Math.trunc(-45.6)); // -45
console.log(~~-45.6); // -45

 

위의 예시와 같이 소수점을 버리는 성질이 있기 때문에 이 점을 이용하면 다음과 같이도 활용해볼 수 있다.😏👍

 

//비트단위 논리연산자이므로 메소드 호출보다 연산 속도가 훨씬 빠르다.
const iterations = 10000000;
console.time("Math.trunc()");
for(let i=0; i<iterations; i++){
    Math.trunc(-45.6); // Math.trunc: 124.700ms
}
console.timeEnd("Math.trunc()");
console.time("~~");
for(let i=0; i<iterations; i++){
    ~~-45.6; // ~~: 21.944ms
}
console.timeEnd("~~");

 

 

 

*아이디어 제공 : 뿌람

반응형