비트이동 연산자

minsub park·2020년 8월 25일
0

JAVA basic

목록 보기
8/8

비트이동연산자?

비트연산자는 정수값을 비트 단위로 연산할 수 있다.
1은 true, 0은 false라고 간주하고 계산한다. 출력 결과도 정수이다.
비트 연산자의 종류로는(&, |, ^, ~, >>, << 등)이 있다.


1. &연산자

정수값을 2진수화 했을 때 and연산으로 모두 true일때만 true값인 1을 리턴한다.

    System.out.println(a & b);
    // a = 0000 0000 0000 0000 0000 0000 0110 1100
    // b = 0000 0000 0000 0000 0000 0000 0101 0101
    // --------------------------------------------
    //     0000 0000 0000 0000 0000 0000 0100 0100 = 68

2. | 연산자

정수값을 2진수화 했을 때 or연산으로 true가 하나라도 있다면 true값인 1을 리턴한다.

    System.out.println(a | b);
    // a = 0000 0000 0000 0000 0000 0000 0110 1100
    // b = 0000 0000 0000 0000 0000 0000 0101 0101
    // --------------------------------------------
    //     0000 0000 0000 0000 0000 0000 0111 1101 = 125

3. ^ 연산자

정수값을 2진수화 했을 때 true(1), false(0)값이 일치하지 않을 때만 true값인 1을 리턴한다.

    System.out.println(a ^ b);
    // a = 0000 0000 0000 0000 0000 0000 0110 1100
    // b = 0000 0000 0000 0000 0000 0000 0101 0101
    // --------------------------------------------
    //     0000 0000 0000 0000 0000 0000 0011 1001 = 57

4. ~ 연산자

정수값을 2진수화 했을때 true와 false 를 모두 바꿔 리턴한다.
비트연산에서의 not은 !가 아니라 ~연산자이다.

    System.out.println(~a);
    // a = 0000 0000 0000 0000 0000 0000 0110 1100 = 108
    // --------------------------------------------
    //     1111 1111 1111 1111 1111 1111 1001 0011 = -109

위의 비트연산자는 어디에 쓰이는가?

이미지 및 영상처리에 사용된다.
예) 마스킹, 오버레이 기법에 사용된다.
예) 색조 변경에 사용된다.

  • 비트 연산 활용의 예
    흑백을 반전시키는 방법:
    빛이 있는 점은 빛을 없애고 (1 --> 0)
    빛이 없는 점은 빛을 넣는다.(0 --> 1)
    => 다음과 같이 흑색의 한 점이 있다.
    00000000 00000000 00000000 (변경전 색: 검정)
    ~
    11111111 11111111 11111111 (변경한 색: 흰색)

5. << 연산자

왼쪽으로 비트를 이동한다. 1 비트 이동할 때 마다 곱하기 2 한것과 같은 효과를 준다.오른쪽 빈자리는 0으로 채운다. 값을 2의 제곱수로 증가시킬 땐 곱하기 연산을 하는 것 보다 왼쪽 비트 이동 연산을 하는 것이 빠르기 때문에 실무에서도 자주 쓰인다.

    int i = 1;
    //      [00000000000000000000000000000001] = 1

    System.out.println(i << 1);
    //     0[0000000000000000000000000000001 ]
    //      [00000000000000000000000000000010] = 2

    System.out.println(i << 2);
    //    00[000000000000000000000000000001  ]
    //      [00000000000000000000000000000100] = 4

    System.out.println(i << 3);
    //   000[00000000000000000000000000001   ]
    //      [00000000000000000000000000001000] = 8

    System.out.println(i << 4);
    //  0000[0000000000000000000000000001    ]
    //      [00000000000000000000000000010000] = 16

음수에 << 연산을 쓰게되면 부호비트에 상관없이 무조건 이동한다. 음수에 쓰게되면 양수로 바뀌어버린다!

 int a = -0x7f_ff_ff_fa; 
 // -21_4748_3642
 System.out.println(a)
    [10000000000000000000000000000110]
System.out.println(a << 1);
   1[00000000000000000000000000001100] = 12

비트이동 연산은 int타입 값에선 0~31까지 유효하다. 만약 31을 넘는 경우 나눈 나머지 값을 비트 이동으로 간주한다.
long타입의 경우 비트 이동은 0~63까지 유효하다. 만약 63을 넘는 경우 64로 나눈 나머지 값을 비트 이동으로 간주한다.


6. >>, >>> 연산자

오른쪽으로 비트를 이동한다. 1비트 이동할 때 마다 나누기 2 한 것 같은 효과를 준다. / 나누기 연산을 수행하는 것 보다 계산 속도가 빨라서 실무에서는 나눗셈 연산이 시간과 CPU사용량이 많이 들기 때문에 소수점 이하까지 정확하게 계산할 것이 아니라면 >> 비트 이동 연산자를 주로 사용한다.
(>>)연산자는 왼쪽 빈자리를 원래 숫자와 같은 부호값으로 채운다.
양수라면 0, 음수라면 1을 채운다.

  • 양수의 경우!
    int i = 105;
    // [00000000000000000000000001101001]

    System.out.println(i >> 1);
    // [ 0000000000000000000000000110100]1
    // [00000000000000000000000000110100]       => 52
  • 음수의 경우!
    int i = -87;
    // [11111111111111111111111110101001]

    System.out.println(i >> 1);
    // [ 1111111111111111111111111010100]1
    // [11111111111111111111111111010100]1      => -44
  • 참고! (>>>)연산자는 오른쪽으로 비트를 이동하는 것은 같지만, 왼쪽 빈자리를 음수 양수 상관없이 무조건 0으로 채운다.
profile
Hello World! 어제보다 나은 코드를 위해

0개의 댓글