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으로 복원하고 싶다면 -120255를 비트 논리곱(&) 연산을 수행하면 된다.

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
서브목차