3.8 비트 논리 연산자
비트 논리 연산자는 bit 단위로 논리 연산을 수행한다. 0과 1이 피연산자가 되므로 2진수 0과 1로 저장되는 정수 타입(byte, short, int, long)만 피연산자가 될 수 있고, 부동 소수점 방식으로 저장되는 실수 타입(float, double)은 피연산자가 될 수 없다.
다음은 비트 논리 연산자의 종류를 보여 준다. 피연산자가 1, 0이라는 것과 산출 결과가 1, 0이라는 점에 주목하자. 1은 true, 0은 false라고 생각한다면 3.7절의 논리 연산자와 차이가 없다.
| 구분 | 연산식 | 설명 | |
|---|---|---|---|
| AND (논리곱) | & |
두 비트 모두 1일 경우에만 연산 결과가 1 | |
| OR (논리합) | ` | ` | 두 비트 중 하나만 1이면 연산 결과는 1 |
| XOR (배타적 논리합) | ^ |
두 비트 중 하나는 1이고 다른 하나가 0일 경우 연산 결과는 1 | |
| NOT (논리 부정) | ~ |
보수 |
45와 25를 비트 논리 연산해 보자. 먼저 45를 2진수로 표현하면 다음과 같다.
00101101 (45)
25를 2진수로 표현하면 다음과 같다.
00011001 (25)
45와 25의 2진수로 비트 논리곱(&)과 논리합(|) 연산을 수행하면 다음과 같다.
45 & 25 = 00001001 (9)
45 | 25 = 00111101 (61)
45와 25의 비트 배타적 논리합(^)과 45의 비트 논리 부정(~) 연산을 수행하면 다음과 같다.
45 ^ 25 = 00110100 (52)
~45 = 11010010 (-46) (최상위 비트가 1이면 음수)
비트 논리 연산자는 byte, short, char 타입 피연산자를 int 타입으로 자동 변환한 후 연산을 수행한다. 따라서 연산 결과도 int 타입이 되므로 int 변수에 대입해야 한다.
byte num1 = 45;
byte num2 = 25;
//byte result = num1 & num2; //컴파일 에러
int result = num1 & num2;
비트 논리 연산이 왜 필요한지 예를 하나 들어 보자. 소형 임베디드 장치의 C 프로그램에서 외부 서버의 자바 프로그램으로 데이터를 전달한다고 가정하자. C 언어에는 uint8_t 타입이 있는데, 이 타입은 1byte 크기를 가지면서 0~255 값의 범위를 가진다.
C 프로그램이 uint8_t 타입 136을 2진수로 보내면, 자바는 2진수를 -120으로 읽게 된다. 그 이유는 자바는 최상위 비트가 1이면 음수로 인식하기 때문이다.
-120을 C 프로그램이 보낸 136으로 복원하고 싶다면 -120과 255를 비트 논리곱(&) 연산을 수행하면 된다.
byte receiveData = -120;
int unsignedInt = receiveData & 255; //136
[예제: BitLogicExample.java]
package ch03.sec08;
public class BitLogicExample {
public static void main(String[] args) {
System.out.println("45 & 25 = " + (45 & 25));
System.out.println("45 | 25 = " + (45 | 25));
System.out.println("45 ^ 25 = " + (45 ^ 25));
System.out.println("~45 = " + (~45));
System.out.println("-------------------------");
byte receiveData = -120;
//방법1: 비트 논리곱 연산으로 Unsigned 정수 얻기
int unsignedInt1 = receiveData & 255;
System.out.println(unsignedInt1);
//방법2: 자바 API를 이용해서 Unsigned 정수 얻기
int unsignedInt2 = Byte.toUnsignedInt(receiveData);
System.out.println(unsignedInt2);
int test = 136;
byte btest = (byte) test;
System.out.println(btest);
}
}
실행 결과
45 & 25 = 9
45 | 25 = 61
45 ^ 25 = 52
~45 = -46
-------------------------
136
136
-120