정수형 타입 연산에서 사용할 수 있는 연산으로, 해당 변수를 2진수로 표현한 값을 통해 연산합니다.
메모리 내 모든 값들은 2진수 형태로 저장하며, 저수준(low-level) 에서 연산을 수행하기 때문에 기본 산술 연산보다 속도가 빠릅니다.
정수 값은 데이터 맨 앞의 비트부호를 포함한 2진수 값으로 표현됩니다.
부호비트가 1
이면 음수를 나타냅니다. 같은 절댓값을 가진 양수와 음수는 2의 보수 관계를 가지며 다음과 같이 표현됩니다.
(short) 2 == 0b1000_0010
(short) -2 == 0b0111_1110
|
) 연산두 피연산의 각각 비트 값에 비트 OR 연산한 결과를 반환합니다. 즉 두 피연산자의 비트 자리에서 하나라도 1
이라면 해당 자리는 1
을 갖게됩니다.
0b0010 | 0b1011 == 0b1011
&
) 연산두 피연산자의 각각 비트 값에 비트 AND 연산(둘 다 1
이라면 1
)한 결과를 반환합니다.
0b0010 & 0b1011 == 0b0010
^
) 연산두 피연산자의 각각 비트 값에 비트 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
*/
~
) 연산~
연산은 단항 연산자로 해당 값이 갖고 있는 비트를 모두 반전 시키는 값을 반환합니다. 부호 비트를 포함해서 반전시킨다는 점을 유의해야합니다.
~0b0010 == 0b1101