비트 단위 연산을 위한 연산자가 따로 존재한다.
먼저 비트는 이진수로 0 또는 1의 값을 갖는다.
비트 단위 연산이란 이진수의 각 비트 값을 연산하는 것을 의미한다.
위의 그림에 나온 이진수를 예로 들자면, 01010010 이라는 이진수의 각 비트마다 (0,1,0,1,0,0,1,0) 모종의 연산을 수행하는 것이다.
Swift에는 NOT, AND, OR, XOR, Shift 연산자가 있다. (Java도 거의 동일한 것 같았다.)
1. NOT 연산자 (~)
: 0과 1이 반대되는 수를 반환한다. (1의 보수에 해당한다.)
~0101 = 1010 이 되는 셈이다.
예를 들어서, 정수 5에 NOT 연산자를 사용하면 (~5) 이는 ~0101으로 인식이 된다.
그러면 0101에서 0과 1을 반전시킨 수인 1010이 반환될 것이다.
print(~5)
이진수 1010을 10진수로 변환해보면 10이 나오므로, 콘솔창에 10이 찍혀야 한다고 예상할 텐데 실제로는 -6 이 나온다.
이는 1010을 그대로 10진법으로 바꾸는 것이 아니라 1010의 2의 보수(Two's complement)를 10진법으로 바꾸기 때문이다.
(2의 보수는 1의 보수에 이진수 1을 더하면 된다.)
1010의 2의 보수는 -6으로, -6이 콘솔에 나오는 것이다.
과정을 종합해보면, ~5를 하게되면 "5를 이진법으로 바꾸고 -> 1의 보수를 계산(?)하고 -> 5의 1의 보수의 2의 보수를 계산하고 -> 계산된 수를 10진법으로 바꾸어 결과값을 내는 것"이다.
따지고 보면 위의 계산은 "5의 2진법 수에 1을 더한 수를 십진법으로 변경하고 -를 붙인 것"과 동일하다.
* 2진수의 1의 보수:
정수 5를 이진수로 나타내면 0101
1의 보수는 0101에서 1을 뒤집어 주면된다.
그러면 5의 1의 보수는 1010이 된다.
* 2진수의 2의 보수:
2의 보수는 1의 보수에 이진수 1을 더해주면 된다.
1010에 1을 더해주면 1011이 된다.
따라서 정수5의 2의 보수는 11이 된다. ("2의 네제곱 - 5" 를 한 값과 같다.)
2. AND 연산자(&)
AND 연산자는 비교하는 이진수의 같은 자리에 둘 다 1이 있는 경우에만 1을 반환한다.
예를 들어서,
정수 5 는 이진수로 바꾸면 -> 0101
정수 7 는 이진수로 바꾸면 -> 0111
두 수 모두 공통으로 1이 들어가 있는 자리에만 1을 유지하고 나머지는 0을 대입하면
0101이 된다.
0101을 십진법으로 바꾸면 5가 되므로 5&7 은 5가 나오게 된다.
3. XOR 연산자(^)
XOR 연산자는 비교하는 이진수의 같은 자리의 값이 다른 경우에만 1을 반환한다.
예를 들어서,
정수 5 는 이진수로 바꾸면 -> 0101
정수 7 는 이진수로 바꾸면 -> 0111
값이 다른 자리에만 1을 넣어주면 0010이 된다.
0010을 십진수로 바꾸면 2가 되므로 5^7은 2가 된다.
4.OR연산자(|)
OR 연산자는 비교하는 이진수에 중 하나라도 1이 들어있으면 1을 반환한다. (둘 다 0인 경우만 0이고 나머지는 1)
정수 5 는 이진수로 바꾸면 -> 0101
정수 7 는 이진수로 바꾸면 -> 0111
둘다 0인 경우만 제외하고 모두 1을 넣어주면 되므로 0111이 된다.
0111을 십진수로 바꾸면 7이 되므로 5|7은 7이다.
'코딩테스트' 카테고리의 다른 글
Integer 나눗셈 시 소수점도 나타나게 하기 (0) | 2022.06.08 |
---|