[JAVA] 연산자 2 - 비트연산자

김민기·2021년 5월 22일
0

Java

목록 보기
7/20
post-thumbnail
post-custom-banner

비트연산자

정수형 타입 연산에서 사용할 수 있는 연산으로, 해당 변수를 2진수로 표현한 값을 통해 연산합니다.

메모리 내 모든 값들은 2진수 형태로 저장하며, 저수준(low-level) 에서 연산을 수행하기 때문에 기본 산술 연산보다 속도가 빠릅니다.

비트 표현

정수 값은 데이터 맨 앞의 비트부호를 포함한 2진수 값으로 표현됩니다.

부호비트가 1 이면 음수를 나타냅니다. 같은 절댓값을 가진 양수와 음수는 2의 보수 관계를 가지며 다음과 같이 표현됩니다.

(short) 2 == 0b1000_0010
(short) -2 == 0b0111_1110

이항 연산자

OR(|) 연산

두 피연산의 각각 비트 값에 비트 OR 연산한 결과를 반환합니다. 즉 두 피연산자의 비트 자리에서 하나라도 1 이라면 해당 자리는 1 을 갖게됩니다.

  • 0b0010 | 0b1011 == 0b1011

AND(&) 연산

두 피연산자의 각각 비트 값에 비트 AND 연산(둘 다 1 이라면 1 )한 결과를 반환합니다.

  • 0b0010 & 0b1011 == 0b0010

XOR(^) 연산

두 피연산자의 각각 비트 값에 비트 XOR(배타적 논리합) 연산한 결과를 반환합니다.

XOR(배타적 논리합)은 비교하려는 두 수의 비트가 같으면 0, 다르면 1 을 갖습니다.

  • 0b0010 ^ 0b1011 == 0b1001

시프트 연산자

비트 시프트 연산자는 비트로 표현된 왼쪽 피연산자의 값을 오른쪽 피연산자가 갖는 정수값 만큼 이동 시키는 연산을 합니다.

왼쪽 시프트(<<)

왼쪽 피연산자의 비트를 오른쪽 피연산자(정수)만큼 왼쪽으로 이동시킵니다. 그 과정에서 부호 비트를 포함한왼쪽의 비트들은 삭제되며 오른쪽의 빈 비트 자리는 0 으로 채워집니다.

실제 값은 2진수의 자리수가 하나씩 증가하므로 * 2가 됩니다.

  • 0b0010 << 2 == 0b1000
//20_000_000_000
int i = (int)Math.pow(10,9) * 2;
printBit(i);
int k = i << 1;
printBit(k);
int l = i * 2;
printBit(l);

//...
private static void printBit(int num) {
		System.out.println(num);
		for (int i = 31; ; i--) {
			System.out.print((num & 1 << i) != 0 ? 1 : 0);
			if (i == 0) {
				break;
			}
			if (i % 4 == 0) {
				System.out.print("_");
			}
		}
		System.out.println();
}

/*
출력 : 

2000000000
0111_0111_0011_0101_1001_0100_0000_0000
-294967296
1110_1110_0110_1011_0010_1000_0000_0000
-294967296
1110_1110_0110_1011_0010_1000_0000_0000

*/

위와 같이 비트이동 시킨 값과 *2 연산값의 비트를 각각 출력해보면 같은 값을 볼 수 있습니다.

이 때 부호비트도 함께 이동하며 해당 변수의 표현 범위 내에서 *2와 같은 동작을합니다.

오른쪽 시프트(>>)

부호비트를 제외한 왼쪽 피연산자의 비트를 오른쪽 피연산자(정수)만큼 오른쪽으로 이동시킵니다. 오른쪽의 비트들은 삭제되며 왼쪽의 빈 비트 자리는 원래 부호비트에 해당하는 값으로 채워집니다.

실제 값은 2진수의 자리수가 하나씩 감소하므로 / 2가 됩니다.

  • 0b0010 >> 1 == 0b0001

부호 없는 오른쪽 시프트(>>>)

오른쪽 시프트 연산과 같으나, 부호비트를 모두 포함하여 이동시키는 연산입니다. 이동 시 빈 왼쪽의 자리는 0 으로 채워집니다.

따라서 음수를 >>> 하게되면 반드시 양수 값을 갖게됩니다.

int val1 = -16;
		int val2 = val1 >> 2;
		printBit(val2);
		int val3 = val1 >>> 2;
		printBit(val3);
//...

private static void printBit(int num) {
	System.out.println(num);
	for (int i = 31; ; i--) {
		System.out.print((num & 1 << i) != 0 ? 1 : 0);
		if (i == 0) {
			break;
		}
		if (i % 4 == 0) {
			System.out.print("_");
		}
	}
	System.out.println();
}

/*
출력 :

-4
1111_1111_1111_1111_1111_1111_1111_1100
1073741820
0011_1111_1111_1111_1111_1111_1111_1100

*/

단항 연산자

NOT, 반전 (~ ) 연산

~ 연산은 단항 연산자로 해당 값이 갖고 있는 비트를 모두 반전 시키는 값을 반환합니다. 부호 비트를 포함해서 반전시킨다는 점을 유의해야합니다.

  • ~0b0010 == 0b1101
profile
민기1
post-custom-banner

0개의 댓글