> For the complete documentation index, see [llms.txt](https://docs.sysout.co.kr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sysout.co.kr/base-language/java/beginner/operator/shift-operator.md).

# 쉬프트 연산

## 쉬프트 연산

이 문서에서는 `쉬프트(Shift) 연산`에 대해서 다룬다.

### 쉬프트 연산이란

쉬프트 연산은 일상 생활에서 흔히 볼 수 있는 연산은 아니다. `비트` 수준에서 이루어지는 계산이기 때문에 프로그래밍에서 접하는 것이 일반적이며, 성능이 우수하다.

### 쉬프트 연산자

쉬프트 연산자의 종류는 다음과 같다.

| 연산자 | 사용 예    | 설명                          |
| --- | ------- | --------------------------- |
| <<  | a << n  | a를 n만큼 left shift           |
| >>  | a >> n  | a를 n만큼 right shift          |
| >>> | a >>> n | a를 n만큼 unsigned right shift |

### 쉬프트 연산 데모 1

```java
import java.lang.*;

public class ShiftOperator1 {
    public static void main(String[] args){
        int a = 7;
        
        int b = a >> 2;
        int c = a << 2;
        int d = a >>> 2;
        
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        System.out.println("c = " + c);
        System.out.println("d = " + d);
    }
}
```

출력 결과는 다음과 같다.

```
7
3
14
3
```

쉬프트 연산을 수행하기 위해서는 숫자를 비트 형태(2진수)로 변환하여 생각해야 한다.

| 변수 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 10진수 |
| -- | -- | -- | -- | -- | -- | -- | -- | -- | ---- |
| a  | 0  | 0  | 0  | 0  | 0  | 1  | 1  | 1  | 7    |

a를 bit로 바꾸어 보면 위와 같다. 알아보기 쉽도록 실제로 4byte(32bit)이지만 1byte(8bit)로 표기했다.

`Left Shift`란 각각의 비트를 왼쪽으로 한 칸씩 옮기는 것을 말한다. 범위를 넘어가는(overflow) 데이터는 버림 처리하며 빈칸은 0으로 채운다.

| 변수     | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 10진수 |
| ------ | -- | -- | -- | -- | -- | -- | -- | -- | ---- |
| a      | 0  | 0  | 0  | 0  | 0  | 1  | 1  | 1  | 7    |
| a << 1 | 0  | 0  | 0  | 0  | 1  | 1  | 1  | 0  | 14   |

결론적으로 `Left Shift`를 한 번 수행할 때마다 2배씩 커지는 효과가 발생한다.

`Right Shift`란 각각의 비트를 오른쪽으로 한 칸씩 옮기는 것을 말한다. 범위를 넘어가는(overflow) 데이터는 버림 처리하며 빈칸은 기존의 자리에 있던 값으로 채운다.

| 변수     | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 10진수 |
| ------ | -- | -- | -- | -- | -- | -- | -- | -- | ---- |
| a      | 0  | 0  | 0  | 0  | 0  | 1  | 1  | 1  | 7    |
| a >> 1 | 0  | 0  | 0  | 0  | 0  | 0  | 1  | 1  | 3    |

`Unsigned Right Shift`는 부호를 고려하지 않고 오른쪽으로 1비트씩 이동하는 것을 말한다. 이는 음수를 예로 들어 설명해야 이해할 수 있다.

| 변수      | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |
| ------- | -- | -- | -- | -- | -- | -- | -- | -- |
| a       | 1  | 1  | 1  | 1  | 1  | 0  | 0  | 1  |
| a >> 1  | 1  | 1  | 1  | 1  | 1  | 1  | 0  | 0  |
| a >>> 1 | 0  | 1  | 1  | 1  | 1  | 1  | 0  | 0  |

빨강 부분이 `right shift`와 `unsigned right shift`의 차이점이다.

{% hint style="info" %}
계산 결과는 int이므로 int보다 작으면 실제 값이 예상 결과와 다르게 나온다.
{% endhint %}
