언어 자료구조 알고리즘/디딤돌 Java 언어 Part1

2.2.4 비트 연산 2.2.5 쉬프트 연산

언제나휴일 2016. 4. 4. 09:20
반응형

2.2.4 비트 연산

 

 비트 연산은 비트 단위로 논리 연산을 수행하는 연산입니다.

 

 비트 연산에는 비트 논리곱(&), 비트 논리합(|), 비트 상호 배제(^), 비트 부정(~)이 있습니다. 이 때 특정 자리의 비트가 1이면 참으로 취급하고 0이면 거짓으로 취급합니다.

 

 비트 논리곱(&)은 비트 단위로 논리곱 연산을 합니다. 예를 들어 6&5를 하면 6은 이진수로 110, 5는 이진수로 101 이므로 6&5의 연산 결과는 이진수 100 10진수 4입니다.

 

 비트 논리합(|)은 비트 단위로 논리합 연산을 합니다. 예를 들어 6|5의 연산 결과는 이진수 111 10진수 7입니다.

 

 비트 상호 배제(^)는 둘이 같은 값이면 거짓이고 다른 값이면 참입니다. 예를 들어 6^5의 연산 결과는 이진수 011 10진수 3입니다.

 

 비트 부정(~)은 단항 연산으로 0인 자리는 1 1인 자리는 0으로 바꿉니다. 1진 보수를 취한 값입니다. 예를 들어 ~6를 수행하면 6은 이진수로 000...110으로 1진 보수를 취하면 111...001입니다. 이는 2진 보수 표기 방식에 의해 10진수 -7을 의미합니다.

 

private static void exBitLogical() {

    System.out.println("6&5 :"+(6&5));

    System.out.println("6|5 :"+(6|5));

    System.out.println("6^5 :"+(6^5));

    System.out.println("~6 :"+(~6));       

}

6&5 :4

6|5 :7

6^5 :3

~6 :-7

[소스 2.14] exBitLogical

 

 

 참고로 어떤 수에 같은 수로 ^ 연산을 두 번 하면 원래 수가 되는 특징이 있어 간단한 보안에 사용할 수 있습니다. 이처럼 같은 키로 암호화와 복호화[1]에 사용하는 것을 대칭형 암호화라 합니다.

 

private static void exExclusive() {

    int original = 0x12345678; //원본 데이터

    int cryptograph = 0;  //암호화 데이터

    int decrypt = 0;        //복화화 데이터

    int key = 0x394A38C9;       //암호화와 복호화에 사용할 키

    System.out.println("원본 데이터: "+original);

    cryptograph = original ^ key; //암호화

    System.out.println("암호화 데이터: "+cryptograph);

    decrypt = cryptograph ^ key; //복호화

    System.out.println("복호화 데이터: "+decrypt);       

}

원본 데이터: 305419896

암호화 데이터: 729706161

복호화 데이터: 305419896

[소스 2.14] exExclusive

 

 

 

2.2.5 쉬프트 연산

 

 쉬프트 연산은 좌항에 있는 피연산자를 우항에 있는 수만큼 비트 자리 이동하는 연산자로 << 는 왼쪽 쉬프트 연산자이고 >> >>> 는 오른쪽 쉬프트 연산자입니다.

 

 왼쪽 쉬프트 연산을 하면 좌항에 있는 피연산자의 값이 우항에 있는 수만큼 왼쪽으로 자리 이동하는데 빈 자리는 0으로 채워집니다.

 

 만약 3을 왼쪽으로 4자리 이동시키면 연산 결과는 48입니다. 설명을 위해 2진수로 얘기하면 이진수 011(10진수 3)을 왼쪽으로 4자리 이동하면 이진수 0110000(10진수 48)입니다.

 

 3; 2진수 0000 0011, 10진수 3

 0000 0000 0000 0000 0000 0000 0000 0011

 3<<4; 2진수 0001 1000 , 10진수 48

 0000 0000 0000 0000 0000 0000 0001 1000

 

 오른쪽 쉬프트 연산은 >> >>>이 있습니다. >>는 빈 자리를 부호 비트로 채우는 쉬프트 연산이고 >>>는 빈 자리를 0을 채우는 쉬프트 연산입니다.

 

 예를 들어 48 >>을 이용하여 3자리 이동하면 연산 결과는 3입니다. 설명을 위해 2진수로 얘기하면 48의 부호 비트는 0이고 뒤쪽 8개의 비트는 0011 0000 입니다. 4자리 오른쪽으로 이동하면 빈자리는 0으로 채워지고 뒤쪽 8개의 비트는 0000 0011이므로 연산 결과는 3입니다. 또한 48 >>>을 이용하여 3자리 이동해도 부호 비트가 0이므로 연산 결과는 똑같이 3입니다.

 

 48; 2진수 0001 1000, 10진수 48

 0000 0000 0000 0000 0000 0000 0000 0011

 48>>4; 2진수 0000 0011 , 10진수 3

 0000 0000 0000 0000 0000 0000 0001 1000

 48>>>4; 2진수 0000 0011 , 10진수 3

 0000 0000 0000 0000 0000 0000 0001 1000

 

 

 하지만 음수를 오른쪽 쉬프트하면 >> >>>의 연산 결과가 다릅니다. 음수를 >> 연산으로 이동하면 빈 자리를 부호 비트에 있는 1로 채워지지만 >>>연산으로 이동하면 빈 자리를 0으로 채우기 때문에 연산 결과가 달라집니다.

 

 -48; 2진수 부호 비트:1 뒤쪽 8비트 1110 1000, 10진수 -48

 1111 1111 1111 1111 1111 1111 1110 1000

-48>>4; 빈자리를 부호 비트 1로 채움, 뒤쪽 8비트 1111 1110, 10진수 -3

 1111 1111 1111 1111 1111 1111 1111 1110

-48>>>4; 빈자리를 0으로 채움, 뒤쪽 8비트 1111 1110, 10진수 268435453

 0000 1111 1111 1111 1111 1111 1111 1111 1110

 

private static void exShift() {

    System.out.println("3<<4 : "+(3<<4));

    System.out.println("48>>4 : "+(48>>4));

    System.out.println("48>>>4 : "+(48>>>4));

    System.out.println("-48>>4 : "+(-48>>4));

    System.out.println("-48>>>4 : "+(-48>>>4));

}

3<<4 : 48

48>>4 : 3

48>>>4 : 3

-48>>4 : -3

-48>>>4 : 268435453

[소스 2.15] exShift



[1] 복호화란 암호화 상태의 데이터를 원래 데이터로 바꾸는 과정을 말합니다.

반응형