일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Visual Studio
- Tips프로그래밍강좌
- tipssoft
- 문법
- VS ERROR
- c#
- 이지스퍼블리싱
- 프로그래밍
- 티스토리
- 함수
- Tips강좌
- Kotlin
- Win32
- Programming
- 리뷰
- doit코틀린프로그래밍
- 알고리즘
- 연산자
- c
- 김성엽
- 백준
- Direct2D
- Javascript
- Desktop
- 지식나눔강좌
- CS
- Windows
- c++
- 포인터
- 배열
- Yesterday
- Today
- Total
F.R.I.D.A.Y.
비트 연산자 : 종류 본문
비트 연산자의 종류와 연산 방법을 알아봅니다.
비트 연산자
& (비트 AND, 비트곱)
비트 AND연산자는 양쪽 피연산자(operand) 모두 참값이어야 1을 반환했던 논리 AND(&&) 연산자와 비슷합니다.
양쪽 두 값의 동일 위치에 존재하는 비트의 값이 모두 1인 경우에 해당 위치의 비트를 1로 하여 반환합니다.
A | B | 연산자 | 결과 |
1 | 0 | & | 0 |
1 | 1 | 1 | |
0 | 1 | 0 | |
0 | 0 | 0 |
이 특성을 이용한 연산 표는 다음과 같습니다.
A | 연산자 | B | Result |
1001 | & | 1010 | 1000 (0x08) |
1100 | 0010 | 0000 (0x00) | |
1110 | 1101 | 1100 (0x0C) |
# &의 이름은
앰퍼샌드라고 부릅니다.
| (비트 OR, 비트합)
비트 AND와 같이 논리 연산자에서 따온 기호로서 논리 OR에서 사용한 파이프(|)를 이용합니다.
양쪽 두 값의 각 자리 비트 중 하나라도 1이면 해당 자리 비트는 1로 하여 값을 반환합니다.
A | B | 연산자 | 결과 |
1 | 0 | | | 1 |
1 | 1 | 1 | |
0 | 1 | 1 | |
0 | 0 | 0 |
이 특성을 이용한 연산 표는 다음과 같습니다.
A | 연산자 | B | Result |
1001 | | | 1010 | 1011 (0x0B) |
1100 | 0010 | 1110 (0x0E) | |
1110 | 1101 | 1111 (0x0F) |
# | 기호의 이름은
특정되지 않았습니다. 파이프, 막대기, 수직선 등 여러 이름으로 불리고 있으니 대표적으로 어떤 이름으로 불린다만 알고 계셔도 좋습니다. 한글 이름 하나, 영어 이름 하나. 이렇게 알아두시는 것이 좋을 것 같습니다. 코드를 작성할 때 알파벳 타이핑을 하다 보니 자연스레 영어 단어를 쓰는 일이 많아지더군요.
~ (비트 NOT, 비트 부정)
물결 모양의 기호를 사용하는 비트 부정 연산자는 피연산자의 값을 비트를 기준으로 반전시킵니다.
A | 연산자 | Result |
0100 1001 | ~ | 1011 0110 |
0011 0011 | 1100 1100 | |
0110 1110 | 1001 0001 | |
1000 1110 | 0111 0001 | |
1010 0010 | 0101 1101 |
이 연산자는 원하는 위치의 비트를 켜고 끌 때도 이용하게 됩니다.
^ (비트 XOR, 배타적 비트합)
이 연산자는 따로 논리 연산자[# 즉, 연산자의 양 쪽에 존재하는 피연산자의 평가값(True, False)이 서로 달라야 참을 반환하는 논리 연산자를 말합니다.]가 존재하지 않습니다. 그래서 논리 연산자를 이용하고 싶으면 직접 코드로 구현해야 하지요.
양쪽 값의 동일 위치 비트가 서로 달라야 해당 위치의 비트가 1로 결정되어 값이 나오게 되는 연산자입니다.
A | B | 연산자 | 결과 |
1 | 0 | ^ | 1 |
1 | 1 | 0 | |
0 | 1 | 1 | |
0 | 0 | 0 |
이 특성을 이용한 연산 표는 다음과 같습니다.
A | 연산자 | B | Result |
1001 | ^ | 1010 | 0011 (0x03) |
1100 | 0010 | 1110 (0x0E) | |
1110 | 1101 | 0011 (0x03) |
이 특성을 이용한 배타적 논리합 연산자를 만들어보고 싶다면 이 링크를 클릭하세요.
<<, >> (시프트 연산자)
이 연산자는 해당 위치의 비트를 좌/우로 한 칸씩 밀어버리는 특성을 가지고 있습니다. 말로는 이해가 쉽지 않을 테니 아래 예제를 참고하세요.
이 특성을 이용한 연산 표는 다음과 같습니다.
A (이진수) | B | 연산자 | Result (이진수) |
1 (0000 0001) | 1 |
<< (L-Shift) |
2 (0000 0010) |
2 (0000 0010) | 2 | 8 (0000 0100) | |
4 (0000 0100) | 1 | 8 (0000 1000) | |
8 (0000 1000) | 1 | 16 (0001 0000) | |
16 (0001 0000) | 2 | 64 (0100 0000) | |
32 (0010 0000) | 1 | 64 (0100 0000) |
표를 보면 A의 값에 B만큼 2가 곱해지는 것을 알 수 있습니다. L-Shift는 사용에 큰 이해가 필요하지 않습니다. 그러나 R-Shift 연산자( >> )의 경우에는 다릅니다.
A (이진수) | B | 연산자 | Result (이진수) |
1 (0000 0001) | 1 |
>> (R-Shift) |
0 (0000 0000) |
2 (0000 0010) | 2 | 0 (0000 0000) | |
4 (0000 0100) | 1 | 2 (0000 0010) | |
8 (0000 1000) | 1 | 4 (0000 0100) | |
16 (0001 0000) | 2 | 4 (0000 0100) | |
32 (0010 0000) | 1 | 16 (0001 0000) |
일반적인 연산의 경우에는 위 표와 같이 B의 횟수만큼 ÷2를 진행한 값을 반환합니다. 그러나 음수의 경우에는 CPU 아키텍처에 따라서, 컴파일러의 종류에 따라 예상과는 다른 값을 반환할 수 있습니다. MSVC를 기준으로 하였을 때, 부호 비트(MSB, Most Significant Bit)로 빈 공간을 채웁니다.
이러한 문제를 해결하기 위해 Shift 연산자를 이용할 때는 부호가 없는 unsigned 자료형을 주로 이용합니다.
Reference.
# index
'DEV > C C++' 카테고리의 다른 글
비트 연산자 : 함수에 인자 넘기기 (0) | 2019.12.31 |
---|---|
비트 연산자 : 메모리 크기 줄이기 (0) | 2019.12.21 |
void 포인터(메모리) (0) | 2019.12.08 |
calloc의 인자는 왜 두 개가 필요할까? (1) | 2019.12.05 |
매크로 함수를 사용할 때 주의할 점 (2) | 2019.11.26 |