이진논리연산자
class 이진논리연산자
{
public static void main(String[] args)
{
int a = 7;
int b = 5;
System.out.printf("%32s\n", Integer.toBinaryString(a));
System.out.printf("%32s\n", Integer.toBinaryString(b));
System.out.printf("%32s\n", Integer.toBinaryString(a&b));
System.out.printf("%32s\n", Integer.toBinaryString(a|b));
System.out.printf("%32s\n", Integer.toBinaryString(a^b));
// 년, 월, 일 분리 프로그램
int birthday = 0x19880815;
// 0x19880815
// 0x 1988(0815) 괄호는 소멸
// 0x00001988(0815)
int year = birthday >>> 16;
// 0x19880815
// 0x00198808(15) 괄호는 소멸 0000 1000->08
// & 0x000000ff 1111 1111->ff
//16진수 : 0~9, a(10), b(11), c(12), d(13), e(14), f(15)
int month = birthday >> 8 & 0x000000ff;
int day = birthday & 0xff; // 0xff 와 0x000000ff 서로 같음
System.out.printf("출생년도 : %x년\n", year);
System.out.printf("출생월 : %02x월\n", month);
System.out.printf("출생일 : %02x일\n", day);
/*
shift : 이동하다.
2진수는 2칸
8진수는 3칸
16진수는 4칸
year = birthday >>> 16;
year를 구하기위해
year = 0x19880815 >>> 16;
위의 코드에서 >>> 오른쪽으로 이동하는데 16진수(4칸)을 짤라낸다는 의미
0x00001988(0815)
*/
// birthday = 0x19880815;
// 0xffff00ff;
// 방법1) &이용한 소거
birthday = birthday & 0xffff00ff;
System.out.printf("%x\n", birthday);
//방법2) ^ 이용한 소거
// birthday = birthday ^ 0x19880815; 1000 0001 1001
// 0x00000800; 1000 0000 0000
birthday = birthday ^ 0x00000800;
System.out.printf("%x\n", birthday);
// 월자리에 12 추가
// birthday = 0x19880015;
// | 0x00001200;
birthday = birthday | 0x00001200;
System.out.printf("%x\n", birthday);
}
}
//~ 는 반대로 바꿈
/*
1. 시프트 연산자
1) >> : 오른쪽으로 주어진 비트 수만큼 이동
: 앞에 비어 있는 빈칸은 부호 비트로 채운다
2) << : 왼쪽으로 주어진 비트 수만큼 이동
: 뒤에 비어 있는 빈칸은 0으로 채운다.
*
문제 : 178
128 64 32 16 8 4 2 1 -> 승수
1 0 1 1 0 0 1 0 -> 2진수로 변환한 코드
바로 위에서 1이 표시된 부분의
승수를 모두 더하면
178이라는 값이 나옴
<시프트 연산자>
비트 열을 좌우로 지시한 만큼 이동시키는(shift) 연산자를 말한다.
C언어 : >> 과 << 만 있음
자바언어 : >>> 연산자도 있음
○ 왼쪽 시프트 연산자 <<
128 64 32 16 8 4 2 1 -> 승수
1 0 1 1 0 0 1 0 -> 2진수로 변환한 코드
178 << 2 : 178 의 이진코드를 왼쪽으로 2비트 시프트 한다.
10110010 : 2 진수로 변환한 코드 값
1011001000 :
왼쪽으로 두칸 밀면서, 비게 되는 오른쪽 두칸은 0 으로 채운다.
그런데, 문제는 왼쪽으로 밀면서 기존의 크기를 넘어서기 때문에
왼쪽으로 넘어선 2개의 비트는 삭제(11001000)
따라서, 10110010 을 왼쪽으로 밀면
왼쪽 두개 비트인 10 은 삭제되고,
오른쪽의 2개 비트는 0으로 채워져
결과값은 11001000 이 된다.
문제 : 178
128 64 32 16 8 4 2 1 -> 승수
1 0 1 1 0 0 1 0 -> 2진수로 변환한 코드
○ 오른쪽 시프트 연산자 >>
178 >> 2 : 178의 이진코드를 오른쪽으로 2 비트 시프트 한다.
10110010
1110110010
오른쪽으로 2비트 이동한후, 비게되는 왼쪽의 2개비트는 1로 채워지고, 오른쪽에서 2비트 넘어간 부분은 삭제된다.
따라서, 10110010 을 오른쪽으로 2비트 시프트하면, 11101100 이 된다.
그런데, 주의할점은, 오른쪽으로 밀면서 왼쪽에 비게되는 비트부분이 무조건 1 로 채워지는 것이 아니라,
밀기전의 최초 첫째자리 값과 동일한 값으로 채워진다는 것이다.
여기에서는 밀기전의 첫째자리값이 1 이었으므로, 1 로 채워진 것이다.
문제 : 178
128 64 32 16 8 4 2 1 -> 승수
1 0 1 1 0 0 1 0 -> 2진수로 변환한 코드
○ 논리 오른쪽 시프트 연산자 >>>
178 >>> 2 : 오른쪽으로 2 비트 시프트한다.
자바에 추가된 논리 시프트는 오른쪽으로 밀면서 비게되는 앞쪽 비트를 무조건 0 으로 채워넣는 것이다.
10110010 -> 밀기전 2진코드
00101100 -> 밀고나서 2진코드
으로 되는 것으로,
역시 오른쪽으로 밀려난 2개 비트 10 은 삭제되고,
비게되는 왼쪽 2비트는 무조건 0으로 채워진다.
따라서 10110010 을 오른쪽으로 논리 시프트 하면, 00101100 이 된다.
예시)
--------------------------------------
public class a{
public static void main(String [] args){
byte a = 10; // 00001010
byte b = 9; // 00001001
byte c = 1; //시프트할 칸수
System.out.println(a + " & " + b + " = " + (a&b)); //논리합
System.out.println(a + " | " + b + " = " + (a|b)); //논리곱
System.out.println(a + " ^ " + b + " = " + (a^b)); //배타적 논리합(xor)
System.out.println("~10 = " + (~a)); //a 의 보수(반전)
System.out.println(a + " << " + c + " = " + (a<<c)); //왼쪽 1비트 시프트(뒤를 0 으로 채움)
System.out.println(a + " >> " + c + " = " + (a>>c)); //오른쪽 1비트 시프트(앞을 밀리기전 첫째자리와 동일한 비트로 채움)
System.out.println(a + " >>> " + c + " = " + (a>>>c)); //오른쪽 1비트 논리 시프트(앞을 0 으로 채움)
System.out.println(-1 * a + " >> " + c + " = " + (-1*a >> c));
}
}
--------------------------------------
/*
출력:
10 & 9 = 8 : 00001000
10 | 9 = 11 : 00001011
10 ^ 9 = 3 : 00000011
~10 = -11 : 11110101
10 << 1 = 20 : 00010100
10 >> 1 = 5 : 00000101
10 >>> 1 = 5 : 00000101
-10 >> 1 = -5 : 11111011
*/
부호가 붙은 정수형에서는 최상위 비트를 부호비트로 사용한다.
0 은 + 를 표시하고, 나머지 비트로 수를 표시한다.
1은 - 를 표시 하고, 나머지 비트를 반전하여 1 을 더한값이 절대값이 된다.
----------------------------------------
쉬프트연산자 >>, >>> 차이점이요.
양의 숫자를 쉬프트 시킬때는 차의가 없습니다.
하지만 음의 숫자는 2진수로 표시할때 맨앞에 부호비트 1이 붙습니다.
>>연산자의 경우는 부호비트는 고정되고 쉬프트 되지만
>>>연산자는 부호비트도 함께 쉬프트가 됩니다.
ex)
System.out.println(-300>>>2);
System.out.println(-300>>2);
실행시키면
1073741749
-75
가 됩니다.
*/
------------------
수업시간 메모
오른쪽으로 밀릴때
양수면 0으로 채우고
음수면 부호로 채움
왼쪽으로 밀면 값이 커짐
32 16 8 4 2 1의 논리에 의해
오른쪾으로 밀면 감소 되고
왼쪽으로 밀면 증가함
-1을 오르쪽으로 밀면 부호비트 1로 채워짐
(빈공간은 부호로 채움)
양수로 밀땐 두개짜로리로 밀든 결과는 ㄱ같음
음수로 2개를 밀면 빈공간은 부호(1)로 채움
움수로 3개 짜리로 밀면 빈공간은 0으로 채움
2개짜리로 오른쪽으로 밀때 부호로채우고
3개짜리는 0으로 채움