> 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/variable/decimal-type/decimal-store-algorithm.md).

# 정수의 저장 원리

## 정수의 저장 원리

이 문서에서는 정수의 저장 원리에 대해 깊이 있게 다룬다.

### 컴퓨터 메모리 체계

컴퓨터는 전기를 이용해 동작하며, 전기를 세게 흘리거나 약하게 흘리는 두 가지 상태를 이용하여 모든 계산을 처리한다. 따라서 데이터 저장 체계도 두 가지 상태인 0과 1로 구분하며 이를 저장할 수 있는 가장 작은 단위를 `비트(bit)`라고 부른다.

`비트`만으로는 데이터 저장의 한계가 있기 때문에, `비트`들을 모아서 하나의 단위를 구상하였고 8개의 `비트`를 모아 `바이트`라는 단위를 만들게 된다.

{% hint style="info" %}
1byte = 8bit = 2^8 종류 = 256종류&#x20;
{% endhint %}

![8bit는 1byte와 같다.](https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_TNZwLuHV9ipYLbvRq%2F-MdHPYOLbmmnu2y6_6nr%2F-MdHQ6USzl30gEnZIwHv%2Fimage.png?alt=media\&token=02e9c2ff-3a99-4632-b2e1-cf8ea692b339)

1바이트는 256개의 값을 표현할 수 있다. 이를 표현하면 다음과 같다.

```
00000000
00000001
00000010
00000011

...

11111110
11111111
```

`00000000`은 0이며 순서대로 번호를 붙이면 `11111111`은 255가 된다. 이는 프로그래머 용 계산기를 통해서도 확인할 수 있다. 하지만 숫자에는 `부호`라는 것이 존재하기 때문에 무조건 0부터 번호를 붙일 수도 없는 상황이다. 하지만 컴퓨터는 양수와 음수 개념을 모르기 때문에 여기서  `보수`가 등장한다.

### 보수

보수는 진법과 합쳐 `2의 보수`, `10의 보수`등으로 불리며, **더하여 밑수가 되는 값**을 말한다. 이해를 위해 좀 더 쉽게 설명하면 **자리수가 고정일 때, 더해서 0이 되도록 만드는 수**가 보수의 정의이다. 2진수일 때는 2의 보수, 10진수일 때는 10의 보수라고 부른다.

만약 자리수가 한 자리인 10진수가 있을 경우, 4에 대한 10의 보는 `6`이다.

$$
4 + 6 = 0
$$

4와 6을 더하면 10이 나오지만, 한 자리라고 정해져 있기 때문에 1은 버려지고 0만 남게 된다. 이러한 특징을 이용하면 우리는 음수의 개념을 몰라도 값을 유추할 수 있게 된다.

다시 컴퓨터가 사용하는 2진수로 돌아와서 **크기를 1바이트로 고정**시키고 생각해본다.

1바이트에서 표현 가능한 가장 큰 숫자는 `11111111`이다. 이 숫자에 얼마를 더하면 `00000000`이 될까?

답은 `1`이다.

$$
11111111 + 00000001 = 00000000
$$

물론 `11111111`과 `00000001`을 더하면 `100000000`이 되지만, **크기가 1바이트로 고정**이기 때문에 넘치는 값(overflow)은 버려진다. 따라서 `00000000`, 즉 0이 된다. 따라서 `11111111`과 `00000001`은 2의 보수 관계이다. 2진수에 있어서는 더해서 0이되는 수라는 의미이다. 이러한 사실들을 바탕으로 우리는 다음과 같이 정리할 수 있다.

* `11111111`과 `00000001`은 더하면 0이된다.
* `11111111`과 `00000001`은 2의 보수 관계이다.
* a + b = 0일 때, a가 1이면 b는 -1이다.
* `00000001`이 1이므로, `11111111`은 -1이라고 볼 수 있다.

![넘침(overflow)이 발생할 경우 해당 데이터는 사라진다.](https://4208234536-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M_TNZwLuHV9ipYLbvRq%2F-MdHPYOLbmmnu2y6_6nr%2F-MdHajgye6gV6Q8LI-zt%2Fimage.png?alt=media\&token=2cefd155-7487-4da6-9ac2-9c740529c4dd)

즉, -1은 다음과 같이 계산한다.

1. 1의 2진수 값을 구한다.
2. 1번의 모든 자리를 뒤집는다(1의 보수)
3. 2번에 1을 더한다.

이를 기호로 표시하면 다음과 같다.

```
-1 = ~1 + 1
```

### 부호를 고려하여 범위 설정(signed)

1바이트를 부호를 고려하여 구분하면 다음과 같이 나눠진다. 값의 범위는 `-128`부터 `127`까지이다.

| 2진수      | 10진수 |
| -------- | ---- |
| 10000000 | -128 |
| 10000001 | -127 |
| 10000010 | -126 |
| ...      | ...  |
| 11111110 | -2   |
| 11111111 | -1   |
| 00000000 | 0    |
| 00000001 | 1    |
| 00000010 | 2    |
| ...      | ...  |
| 01111101 | 125  |
| 01111110 | 126  |
| 01111111 | 127  |

따라서 부호를 고려하여 1바이트 범위 내에서 계산을 수행할 경우 `127 + 1` 은 `128`이 아닌 `-128`이다. 따라서 순환형 구조를 가진다라고 표현한다. 또한 음수들을 살펴보면 맨 앞자리가 1이라는 것을 알 수 있으며 이러한 특징을 이용하여 맨 앞자리를 `부호 비트(signed bit)`로 부른다. 주의할 점은 애초에 부호를 고려해서 만든 것이 아니라 만들고 나서 보니 부호 비슷한 역할을 수행한다라고 보는 것이 앞으로 이해에 도움이 될 것이다.

### 부호를 고려하지 않고 범위 설정(unsinged)

부호를 고려하지 않을 경우 1바이트 범위 내에서 `0`부터 `255`까지의 값을 가진다.

| 2진수      | 10진수 |
| -------- | ---- |
| 00000000 | 0    |
| 00000001 | 1    |
| 00000010 | 2    |
| ...      | ...  |
| 11111101 | 253  |
| 11111110 | 254  |
| 11111111 | 255  |

부호를 고려하지 않을 경우 `부호비트`가 발생하지 않는다.

### 결론

각각의 정해진 크기에 따라 `signed`와 `unsigned`로 범위를 나누면 다음과 같다.

| 크기    | signed                                                  | unsigned                        |
| ----- | ------------------------------------------------------- | ------------------------------- |
| 1byte | -128 \~ 127                                             | 0 \~ 255                        |
| 2byte | -32,768, \~ 32,767                                      | 0 \~ 65,535                     |
| 4byte | -2,147,483,648 \~ 2,147,483,647                         | 0 \~ 4,294,967,295              |
| 8byte | -9,223,372,036,854,775,808 \~ 9,223,372,036,854,775,807 | 0 \~ 18,446,744,073,709,551,615 |
