비트 연산(Bitwise operation)은 한 개 혹은 두 개의 이진수에 대해 비트 단위로 적용되는 연산입니다.
사람한테는 10진수가 익숙하긴 한데 컴퓨터는 2진수가 편하다는군요. 2진수 100101을 10진수로 표시하면 아래와 같습니다. 100101 = (1 * 25) + (0 * 24) + (0 * 23) + (1 * 22) + (0 * 21) + (1 * 20) = 32 + 4 + 1 = 37 |
컬러조작에서 자주 사용되기 때문에 컬러 값을 조작하는 것으로 비트연산자를 설명할까합니다.
아래 표를 보면 16진수 0은 2진수로 0입니다. 그리고 16진수 F는 2진수로 1111입니다. 잘 기억해주세요.
10진수 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16진수 |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
2진수 |
0000 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
쉬프트 연산자
16진수 0xFF0000은 빨간색입니다. 2진수로는 아래와 같습니다.
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
이 0xFF0000을 오른쪽으로 8칸 보내면
0xFF0000 >> 8
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0xFF00이 됩니다. 그럼 초록색이 되는군요. 다시한번 >> 8을 하면 이제 파란색이 되겠군요.
쉬프트 연산은 이처럼 2진수의 자리수를 이동시키는 것입니다.
AND 연산자
0xF845A3 이란 값은 분홍빛입니다.
이 색에서 RGB값을 추출해 내보려고 합니다.
0xF845A3을 2진수 테이블을 만들어 보면 아래와 같습니다.
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
먼저 R(red)를 먼저 추출해 봅시다. 오른쪽 쉬프트 16번 하면 되겠군요.
0xF845A3 >> 16 간단하네요.
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
이제 G(green)을 해봅시다. 8칸을 오른쪽으로 보내고 빨간 녀석을 없애버려야 하는데… 흠…이제 AND연산자의 성질이 필요해지네요.
AND 연산은 두 값의 각 자릿수를 비교해, 두 값 모두에 1이 있을 때에만 1을, 나머지 경우에는 0을 계산합니다.
0 & 0 = 0 |
0 & 1 = 0 |
1 & 0 = 0 |
1 & 1 = 1 |
따라서 0xF845A3을 8칸 보낸 0xF845 에 0x00FF(=0xFF)를 AND 연산하면
& |
0000000011111111 1111100001000101 |
0000000001000101 |
0과는 무조건 0이되기 때문에 1000101만 남는군요. 1000101은 우리가 추출하려던 green영역 값 0x45를 얻었습니다.
0 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
이제 남은 파란색영역도 그린과 마찬가지 입니다. 이번에는 시프트가 필요없겠네요.
그냥 0xF845A3에 0x0000FF(=0xFF)만 AND 연산 해주면 되겠습니다.
1 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
var a : int= 0xF845A3;
trace((a>>16).toString(16)); //f8
trace((a>>8&0xFF).toString(16)); //45
trace((a&0xFF).toString(16)); //a3
OR 연산자
이제 어렵게 나눈 R, G, B를 다시 합치려 합니다.
16칸을 쉼없이 달려온 R을 다시 자기 자리로 떠나 보내야 하는군요.
쉽죠 뭐 왼쪽으로 16번 시프트해주기만 하면되죠. G는 8번이었죠? B는 그대로 있으면 됩니다.
OR연산자는 AND연산자와 달리 참(1)하나라도 있으면 참이라고 인정해주는 아주 착한 녀석입니다. 따라서 OR 연산은 두 값의 각 자릿수를 비교해, 둘 중 하나라도 1이 있다면 1을, 아니면 0을 계산합니다.
0 | 0 = 0 |
0 | 1 = 1 |
1 | 0 = 1 |
1 | 1 = 1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
따라서 위치이동시킨 R, G, B를 OR연산을 하면 원래의 0xF845A3로 돌아오게 됩니다.
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
Adobe의 devnet에 좋은 기사가 있습니다. http://www.adobe.com/devnet/flash/articles/bitwise_operators.html 32bit unsigned bitwise shift 연산자 관련한 글 http://www.bit-101.com/blog/?p=1054 |