프로그래머스 코딩테스트를 풀면서 다른 사람들의 코드를 많이 접하게 됬는 데, 그 중에서 ~~를 사용한 코드를 보고 ~ Bitwise Not (~) 연산자에 대해 정리해보기로 했다.
✨ ~ 연산자
비트를 반전 시킨다. 다른 비트 연산자와 마찬가지로 연산 전에 부호가 있는 32비트 정수로 변경한 후 연산을 진행한다.
자바스크립트는 숫자를 표현할 때, 64 bit 부동소수점 방식을 사용한다.
그러나 모든 비트연산들은 연산 전에 32비트 정수로 변환하고 비트 연산을 진행한다. 연산이 끝난 후, 다시 64비트로 변환한다.
✨ ~를 하나만 쓰는 경우
~N은 -(N+1)을 반환한다.
const a = 5; // 0000 0000 0000 0000 0000 0000 0000 0101
const b = -3; // 1111 1111 1111 1111 1111 1111 1111 1101
console.log(~a); // 1111 1111 1111 1111 1111 1111 1111 1010
// expected output: -6
console.log(~b); // 00000000000000000000000000000010
// expected output: 2
비트를 전부 반전시킨 값을 계산하면 ~N은 -(N+1)이 된다.
✨ ~~를 두 개 쓰는 경우
숫자의 소수점을 없애준다.
위에서 ~ 연산자에대해 설명한 것처럼 비트 연산자를 사용하면 32비트 정수로 변환한 후에 연산을 수행한다.
따라서 ~를 사용하는 순간 이미 소수점이 사라지게된다.
그러나 우리가 원하는 값은 원본값에서 소수점을 없앤 값이기때문에 ~을 두번 사용해 원래 상태로 되돌려주는 것이다.
~~(5.5) // 5
~~(-5.6) // -5 , Math.floor(-5.5)는 참고로 -6 이다.
undefined와 null을 0으로 변경해준다.
~~(undefined) // 0
~(undefined) // -1
~~(null) // 0
~(null) // -1
undefined와 null에 ~~를 적용하면 0이 되는 이유는 무엇일까?
Bitwise Not ~ 의 자바스크립트 스펙
undefined와 null에 ~~를 적용하면 0이 되는 이유는 자바스크립트 Bitwise NOT의 스펙을 보면 알 수 있다.
1. 표현식을 평가한다.
2. 입력받은 값을 Numeric으로 변환한다. 이때, undefined와 Null은 아래와 같이 변환된다.
3. 변환된 값의 타입을 확인하는 데, NaN과 0 모두 Number 타입이기 때문에 4번 If문을 타게 된다.
4. Nuber::bitwiseNOT을 실행한다.
5. 비트 연산들은 모두 32비트 정수로 변환 한 후에 비트 연산을 실행한다. 그래서 해당 값에 ToInt32을 해주는 것이다.
6. ToInt32를 보면 NaN, +0인 경우에 +0을 반환한다.
7. 결론은 ~(undefined)와 ~(null)은 ~0과 값이 같다는 의미다.
~null // -1
~undefined // -1
~0 // -1
8. -1에 다시 ~를 해주면 0이 된다. 따라서 undefined와 null에 ~~를 해주면 0이 된다!
~~(undefined) -> ~~(0) -> ~(-1) -> 0
✨ Math.trunc나 Math.floor 대신 ~~를 써도 되는 걸까?
여러 검색 결과들을 보면 ~~가 Math.trunc보다 속도가 빠르다고 한다. 그러나 그 차이는 브라우저 마다 다르고 매우 큰 편도 아니다. 그리고 나처럼 ~~가 왜 소수점을 제거하는 지 모르는 사람도 많을 거라고 생각한다.
보자마자 의미를 파악하기 쉬운 코드가 좋은 코드라고 생각한다. 리액트를 공부하다보니 선언적 프로그래밍 개념이 자주 나온다. 선언적 프로그래밍을 쉽게 이야기하면 어떤 방법으로 돌아가냐를 나타내는 게 아니라 이게 무슨 일을 하는지를 보여주는 프로그래밍 방식이다.
즉, 소수부분을 삭제하기 위해서 ~~를 사용해 어떤 방법을 쓰는 것 보다는 Math.trunc가 소수를 없애는 일을 한다는 코드가 더 좋다고 생각한다.
'공부 > 자바스크립트' 카테고리의 다른 글
[js] 프로토타입 체인 (0) | 2022.11.21 |
---|---|
[js] 객체지향 프로그래밍 (0) | 2022.11.18 |
[js]자바스크립트 클래스 (0) | 2022.11.18 |
[js] 객체 구조 분해 할당과 얕은 복사 방식들 (0) | 2022.11.09 |
[js] 원시자료형과 참조자료형의 차이 (0) | 2022.11.07 |
댓글