자바스크립트는 모든 것이 10진수 단위로 처리되며 2진수 처리방법도 있지만 보기 힘들다
성능 문제가 심각하지 않다면 일반적 숫자 개념으로도 코드를 짤 수 있으므로 많이 쓰이지 않는다
알고리즘을 풀다 보니 연산자를 사용해 신기한 풀이 방법이 있어서 연산자에 대한 글을 쓰려고 한다
JavaScript에는 생각보다 여러가지 비트 연산자들이 존재한다
논리 비트 연산자부터 비트를 몇 칸씩 움직이는 연산자, 비트들의 값을 뒤집는 연산자도 있다
이런 연산자들이 무한한 2진수에서 계산을 하는 것은 아니고 32bit int를 기준으로 계산한다
사실 무슨 말인지 글을 쓰고 있는 지금도 잘 모르겠다
보통 많이 사용하는 && AND
연산자는 true / false
를 이용해 연산하지만 2진 AND 연산자는 &
하나로 사용한다
10 & 12;
// 8 출력
먼저 10은 이진수로 1010, 12는 이진수로 1100으로 바꾸어 준다
두 숫자에서 자리가 둘 다 1인 부분만 걸러서 1로 처리 하여 1000이 된다
그런 다음 JavaScript는 10진수를 기본으로 사용하기 때문에 10진수로 변환한다
1000은 십진수로 8이니 결과는 8이 된다
AND 연산자와 같이 OR 논리 연산자도 |
하나만 사용한다
10 | 12;
// 14 출력
& AND 연산자와 같이 10진수를 이진수로 변경하고 이번에는 두 숫자에서 자리가 둘 중 한 자리만이라도 1이 있다면 1로 지정하여 1110이 된다
1110은 십진수로 14이니 결과는 14가 된다
해당 연산자는 처음 보는 연산자이다
두 개의 비트가 같으면 0, 다르면 1을 반환하는 특이한 성질을 가지고 있다
10 ^ 12;
// 6 출력
각 비트들에 대해 같은 값을 가지고 있는지 체크를 한다
만약 비트의 값이 같으면 0으로 처리하고 같지 않을 경우 1로 처리한다
10의 경우 1010, 12의 경우 1100이므로 첫째 자리는 같기 때문에 0, 둘째와 셋째 자리는 다르기 때문에 1, 넷째 자리는 같으므로 0으로 처리한다
0110으로 처리되므로 십진수로 6이니 결과는 6이 된다
부정 논리 연산자는 특이하게, 피연산자(대상이 되는 수)가 1개 밖에 들어가지 않는다
!
연산자와 역할이 비슷하며 각 비트들의 값을 모두다 뒤집는다
~18;
// -19 출력
18의 경우 이진수가 1 0010 이므로 각 비트들의 값을 모두 뒤집었을 경우 0 1101이 된다
이럴 경우 숫자의 음/양이 바뀐다
이유는 JavaScript는 비트 단위 연산을 할 경우에 32비트 int를 기준으로 연산을 하기 때문이다
32비트 int에서는 가장 앞 비트가 -2147483648을 나타낸다
-19 = 1111 1111 1111 1111 1111 1111 1110 1101
이건 솔직히 무슨 말인지 잘 모르겠다
왜 뒤집었을 경우 0 1101인데 앞에 1111이 무수히 붙는 것인지 32비트 int에 대해 공부해보면 이해할 수 있으려나..
두 값을 비교하거나 비트들을 밀어주는 연산자이다
쉬프트 연산자들은 모두 비트를 몇칸씩 밀어주는 역할을 한다
10진수에서 굳이 따지자면 곱하기 10이나 나누기 10의 역할을 해주는 연산자들이다
<< 왼쪽 쉬프트 연산자
15 << 2;
// 60 출력
수 << 칸수
로 사용할 수 있다
15에서 비트 단위로 2칸을 밀어 주면 15의 이진수인 1111이었던 비트들이 왼쪽으로 밀려나면서 11 1100이 된다
이 경우 11 1100을 10진수로 변환하면 60이 된다
2진수이기 때문에 몇 칸을 밀어 주냐에 따라서 2의 제곱 만큼 수가 곱해진다
10진수에서 15를 두 칸 왼쪽으로 밀면 1500이 된다
1500은 15에서 15 * (10 * 10)
을 해야 만들어 진다
이와 같이 2진수에서도 이런 규칙이 적용된다
15에서 4칸을 민다면 15 * (2 * 2 * 2 * 2)
가 되고 240이 나온다
이런 계산을 이용해 제곱을 간단히 할 수도 있다
>> 오른쪽 쉬프트 연산자
왼쪽 쉬프트 연산자는 수를 점점 0에서 멀리 떨어지도록 만든다
반대로 오른쪽 쉬프트 연산자는 0으로 점점 가까워지게 만든다
비트들을 오른쪽으로 미는 기능을 가지고 있기 때문이다
-11 >> 2;
// -3 출력
-11의 경우 이진수는 11..0101이고 -3의 경우 11..1101이므로 오른쪽으로 두칸 밀게 되어 가장 왼쪽에는 기존에 있던 첫번째 비트가 오고 가장 오른쪽 비트들은 소멸된다
그렇기 때문에 오른쪽 쉬프트 연산자는 2배, 4배 같은 규칙성은 없다
앞서 알아보았던 일반적 오른쪽 쉬프트의 경우 첫번째 비트를 왼쪽에 넣는다
음수에서는 맨 왼쪽에 있는 양/음수 제어 비트를 그대로 두어야 -4, -2 형식으로 쉬프트될 수 있기 때문이다
하지만 특이한 오른쪽 쉬프트 연산자의 경우 한칸을 밀 때마다 왼쪽에 0이 하나씩 붙는다
-11 >>> 2;
// 1073741821 출력
일반적인 쉬프트 연산자들과는 다르게 맨 왼쪽의 비트가 음의 끝 수를 의미한다
하지만 위의 경우 -11의 이진수는 11..0101 인데 왼쪽에 0이 붙음으로 0011..1101이 되어 다른 수가 출력된다