비트 연산_AND 연산/OR 연산/ XOR 연산/ NOT 연산 / Shift 연산 / 비트의 특정 인덱스 추출(업데이트)
비트 연산
0과 1로 이루어진 이진수의 비트 별 연산
AND 연산(&)
두 비트가 모두 1일 때만 1인 연산
0 0 1 1
0 1 0 1
--------
0 0 0 1
OR 연산(|)
두 비트 중 하나라도 1이면 1인 연산
0 0 1 1
0 1 0 1
--------
0 1 1 1
XOR 연산(^)
두 비트가 다르면 1인 연산
1 1 0 1
0 1 0 1
--------
1 0 0 0
NOT 연산(~)
0을 1로, 1을 0으로 변환하는 연산
0 1 0 1
--------
1 0 1 0
Shift 연산
- Left shift: 비트들을 왼쪽으로 k칸씩 옮기고 남는 자리에 0을 채우는 연산 (x << k)
- Right shift: 비트들을 오른쪽으로 k칸씩 옮기는 연산(옮기고 잘린 데이터는 버림) (x >> k)
1 0 0 1 << 2
---------------
1 0 0 1 0 0
1 0 0 1 >> 2
---------------
1 0
특정 인덱스의 값을 추출하는 법
num = 12 = 1 1 0 0(2) 에서 i = 2 번째 인덱스의 값이 1인지 0인지를 판단하는 식을 세워보자. (인덱스는 뒤에서 부터 0으로 시작)
1 1 0 0
--------
0 ? 0 0
i 번째 비트를 제외한 나머지 비트를 0으로 만들고, i번째 비트는 num의 i번째 비트가 그대로 내려오게 한다면, 해당 결과가 양수일 때 i번째 인덱스 값은 1, 해당 결과가 0일 때 i번째 인덱스 값은 0이라 말할 수 있다.
어떤 수 x와 0의 & 연산은 무조건 0이 되고,
어떤 수 x와 1의 & 연산은 x 가 되므로,
1 1 0 0
0 1 0 0
-------- &
0 1 0 0
와 같이 i번째 인덱스는 1, 나머지는 0으로 이루어진 이진수와 & 연산을 수행한 결과를 보면 된다.
즉, num의 i번째 인덱스를 추출하는 식은 (num&(1<<i)) > 0 ? 1 : 0 이 된다.
특정 인덱스의 값을 1로 셋팅하는 법
num = 12 = 1 1 0 0(2) 에서 i = 1 번째 인덱스의 값을 1로 셋팅해보자.
1 1 0 0
--------
1 1 1 0
i번째 인덱스를 제외한 모든 비트는 num의 비트 값이 그대로 내려오게 하고, 1로 바꿀 인덱스 비트만 무조건 1이 되도록 하면 된다.
어떤 수 x와 1의 |(OR) 연산은 무조건 1이 되고,
어떤 수 x와 0의 |(OR) 연산은 x가 되므로,
1 1 0 0
0 0 1 0
-------- |
1 1 1 0
와 같이 1번째 인덱스는 1, 나머지는 0으로 이루어진 이진수와 |(OR) 연산을 수행하면 된다.
즉, num의 i번째 인덱스 비트를 1로 셋팅하는 방법은 num | (1<<i)가 된다.
특정 인덱스의 값을 0로 셋팅하는 법
num = 12 = 1 1 0 0(2) 에서 i = 2 번째 인덱스의 값을 0로 셋팅해보자.
1 1 0 0
--------
1 0 0 0
i번째 인덱스를 제외한 모든 비트는 num의 비트 값이 그대로 내려오게 하고, i번째 비트만 무조건 0이 되도록 하면 된다.
어떤 수 x와 0의 & 연산은 0이 되고
어떤 수 x와 1의 & 연산은 x가 되므로,
1 1 0 0
1 0 1 1
-------- &
1 0 0 0
와 같이 i번째 비트는 0, 나머지 비트는 1로 이루어진 이진수와 & 연산을 수행하면 된다.
i번째 비트는 0, 나머지는 1로 이루어진 이진수는 ~(1<<i) 이다.
즉, num의 i번째 인덱스 비트를 0으로 셋팅하는 방법은 num & (~(1<<i))가 된다.