본문 바로가기

JAVA 부족한 부분 공부

비트 연산자, 시프트 연산자

1. 비트 연산자 : 컴퓨터가 쉽게 이해하는 연산 기호

개발자가 직접 bit를 조작하면 연산이 빨라진다는 장점이 있음.

 

1) I(OR): 양쪽 데이터의 비트의 값을 OR 조건으로 따져서 한쪽 bit가 1이면 무조건 1의 결과를 낸다.

2) &(AND): 양쪽의 비트가 모두 1이면 1이고, 아니면 0의 결과를 낸다.

3) ^(XOR): 양쪽의 비트가 서로 다르면 1이고, 아니면 0의 결과를 낸다.

출처: https://m.blog.naver.com/PostView.nhn?blogId=akohong&logNo=220801614365&proxyReferer=https:%2F%2Fwww.google.com%2F

 

※ JAVA에서 비트 연산자를 사용한 byte 양수표현 및 0xff 사용법

자바에서 byte 자료형의 범위는 -128 ~ 127 이다. 8개의 비트를 사용하니 256까지 표현하리라 착각하기 쉽다.

하지만 byte의 맨 아의 비트는 부호를 표현하기 때문에 사실상 7개의 비트로만 수를 표현하게 된다.

ex.

int n = 150;

System.out.println(Integer.toBinaryString(n)); //returns 10010110

 

byte b = (byte) n;

System.out.println(b); // returns -106

 

byte 자료형의 범위가 음수, 양수 모두 포함하려다보니 부득이하게 127을 넘어서는 숫자부터 음수로 인식을 하게 된다.

150이라는 int형 숫자(=10010110)에서 보듯 맨앞의 비트가 1이므로 음수로 인식해서 -106 이라는 숫자가 리턴된다.

여기서 변함없는 것은 10010110 이라는 비트열이다. 이 byte를 150 으로 보이게 할 수 있는 방법은 없을까?

다시 말해 -128~127의 범위가 아닌 0~255의 범위의 숫자로 표현할 수 있을까?

 

힌트는 비트 연산자 "&" 에 있다.

int n = 150;

System.out.println(Integer.toBinaryString(n)); //returns 10010110

 

byte b = (byte) n;

System.out.println(b); // returns -106

System.out.println(b & 0xff); // returns 150

 

마지막 줄에 의미하는 0xff 는 표현식을 16진수로 했을 뿐이지 십지수로는 255, 이진수로는 11111111 이라는 숫자일뿐이다. 아무 이진수를 가지고 이진수 11111111과 & 비트 연산자를 사용해서 연산하면 무조건 같은 값이 나올텐데 왜 이런 짓을 했을까?

 

11111111111111111111111110010110

00000000000000000000000011111111

----------------------------------------------- (& 연산)

00000000000000000000000010010110

 

0xff(=255) 는 int형이며, int형은 4byte 데이터 형식이라서 32자리 비트중 맨 뒤에서 8번째 비트가 1이라고 마이너스로 인식하는 일따위는 없어지게 되는것 이다.

 

 

(출처: emflant.tistory.com/133)

 

2. 쉬프트 연산자(비트 이동 연산자)

 

1) x << y : 정수의 x의 각 비트를 y만큼 왼쪽으로 이동시킵니다.(빈자리는 0으로 채워진다.)

2) x >> y : 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킵니다. (빈자리는 정수 a의 최상위 부호비트와 같은 값으로 채워진다.)

3) x >>> y : 정수 x의 각 비트를 y만큼 오른쪽으로 이동시킵니다. (빈자리는 0으로 채워진다.)

출처: https://coding-factory.tistory.com/521

 

 

※ 연산자 우선순위

출처: https://dgblog.tistory.com/11