> 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.md).

# 정수

## 정수

정수는 **소수점이 없는 숫자**를 말한다. 자세한 저장 원리는 [정수의 저장 원리](http://www.sysout.co.kr/home/webbook/page/read/1326) 부분을 참고한다. 정수를 이용할 때 알아야 할 내용들은 다음과 같다.

* 정수는 여러 종류가 있으며, 각각의 형태 마다 범위가 다르다.
* 정수는 순환형 구조를 가진다.
* 정수의 연산 결과는 정수이다.

이해를 돕기 위해 커피숍을 예로 들어 설명한다.

![스타벅스 커피숍 컵 사이즈(출처 : https://post.naver.com/viewer/postView.nhn?volumeNo=8647110)](/files/-MdHNX1beiZiBTJUeCmp)

우리는 커피를 마실 때 원하는 취향에 따라 다양한 크기를 선택할 수 있다. 그리고 크기를 말하지 않아도 제공되는 기본적인 사이즈가 존재한다. 여기서 궁금한 점은 크기가 왜 저렇게 정해졌을까? 라는 부분이다. 결론부터 이야기하면 `알 수 없다`이다. 시장조사를 해본 결과 합리적이라고 판단했을 수도 있고, 심심해서일 수도 있다. 하지만 어떠한 기준에 의해 컵들의 크기가 정해져 있으며, 우리는 이것들을 사용하고 있다는 것이 중요하다.

커피를 고를 때 다음과 같이 주문한다고 가정해보자

> 아메리카노 354mL 주세

상상만 해도 피곤하지 않는가? 일반인들은 숫자를 싫어한다. 따라서 `236`, `354`같은 기억하기 힘든 숫자보다 기억하기 쉬운 이름을 붙이는 것이 좀 더 효율적이다.

> 아메리카노 Tall 사이즈 주세요

같은 의미지만 훨씬 더 쉽게 느껴진다. 미리 크기에 대한 약속이 정해져 있기 때문에 위와 같은 형태의 주문이 가능한 것이다.

만약 크기를 이야기하지 않았다고 가정해보자.

> 아메리카노 주세요

과연 매장 직원은 우리에게 무슨 사이즈의 커피를 줄까? 아마 `Tall` 사이즈일 것이다. 크기를 이야기 하지 않을 경우 기본값으로 지정된 크기를 제공하도록 약속되어있기 때문일 것이다.

이처럼 커피숍에서 벌어지는 일들이 프로그래밍에도 그대로 적용된다.

* 정수를 표현하기 위해 1byte, 2byte, 4byte, 8byte의 크기에 해당하는 단위를 사용하기로 약속한다.
* 크기를 매번 이야기하기 힘들기 때문에 별칭을 붙여 각각 `byte`, `short`, `int`, `long`이라고 부른다.
* 정수 데이터가 크기와 관련된 표기 없이 존재한다면 기본값인 `int`로 생각한다.

### 정수 예제 1

```java
import java.lang.*;

public class DecimalExample {
    public static void main(String[] args){
        //byte는 -128 ~ 127의 범위를 가진다.
        byte a = 10;
        System.out.println(a);
        
        //short는 -32768 ~ 32767의 범위를 가진다(현재 사용하지 않는다)
        short b = 10;
        System.out.println(b);
        
        //int는 약 -21억 ~ +21억 의 범위를 가진다(정수의 기본 자료형)
        int c = 10;
        System.out.println(c);
        
        //long은 약 -900경 ~ +900경 의 범위를 가진다(가장 큰 정수)
        long d= 10;
        System.out.println(d);
    }
}
```

필요한 데이터에 맞게 사용할 수 있으며, `short`는 과거 16bit 체제에서의 프로그램들과 호환을 위해 둔 자료형으로 현재는 거의 사용하지 않는다. 또한 `byte`는 주로 물리적인 데이터를 다룰 때 사용하며 특별한 경우가 아니면 `int`를 쓰고, 크기가 더 큰 형태가 필요할 경우 `long`을 사용한다.

### 정수 예제 2

```java
import java.lang.*;

public class DecimalExample2 {
    public static void main(String[] args){
        byte a = 10;
        byte b = 20;
        //byte c = a + b;//이 코드는 오류가 발생한다.
        int c = a + b;
        System.out.println(c);
    }
}
```

위의 예제를 통해서 `int`보다 작은 형태의 계산은 결과가 `int`로 나옴을 알 수 있다. 자바에서는 정수의 기본형태가 `int`이기 때문에 `int`보다 작은 형태들의 계산은 기본 단위인 `int`로 처리함을 유의해야 계산상의 실수를 하지 않는다. 하지만 앞서 말한 것처럼 `byte`는 물리적인 데이터를 다룰 때 주로 사용하기 때문에 위와 같은 상황은 자주 생기지 않는다.

### 정수 예제 3

```java
import java.lang.*;

public class DecimalExample3 {
    public static void main(String[] args){
        int a = 1234567;
        int b = 7654321;
        int c = a * b;
        System.out.println(c);
    }
}
```

계산 결과를 보면서 실제 계산기로 수행한 결과와 일치하는지를 따져본다.

![계산기로 계산한 결과](/files/-MdHPH79Q5F7RlRya7vf)

계산기로 수행한 값은 위와 같지만 실제 결과는 `844062807`이 나오는 것을 확인할 수 있다. 이러한 문제가 생기는 원인은 정수는 `순환형 구조`를 가지기 때문이다. 순환형 구조를 이해하려면 비트와 메모리 체계를 알아야 하므로 [정수의 저장 원리](http://www.sysout.co.kr/home/webbook/page/read/1326)에 대해서 살펴봐야 한다. 간단히 설명하면 다음과 같이 볼 수 있다.

![정수의 순환형 구조를 이해하기 위한 순환형 수평선](/files/-MdHPNZXCJ9yBMH5qbAQ)

숫자가 수평선이 아니라 원형으로 배치된다고 가정해보면 **가장 큰 수**와 **가장 작은 수**는 이어지게 된다. 따라서 숫자가 계속 커지다가 감당할 수 있는 범위를 넘어가게 되면 `뒤집히는 현상`이 발생하게 된다. 이는 과거 싸이의 강남스타일이 유튜브 조회수 체계를 송두리째 바꿔버린 기록적인 사건의 숨겨진 원리이다.

관련 기사 링크 : [연합뉴스 기사](https://www.yna.co.kr/view/MYH20150311010800038)

따라서 위의 예제는 잘못된 형태이며, `int`로 감당할 수 없기 때문에 형태를 `long`으로 변경해야 한다.

```java
import java.lang.*;

public class DecimalExample3_1 {
    public static void main(String[] args){
        long a = 1234567L;
        long b = 7654321L;
        long c = a * b;
        System.out.println(c);
    }
}
```

실행하면 결과가 정상적으로 나오는 것을 확인할 수 있으며, 주의할 점은 `long`에 해당하는 리터럴에는 `L`이 마지막에 추가되어야 한다는 것이다. 대소문자는 구분하지 않지만, 소문자는 `1`과 혼동되기 때문에 대문자료 표기하는 것이 일반적이다.

만약 `long`으로도 표현하기 어려운 값이라면 자바에서 기본적으로 제공되는 형태로는 방법이 없으며 다른 도구를 이용해야 한다.

### 정수 데모 4

```java
import java.lang.*;

public class DecimalExample4 {
    public static void main(String[] args){
        int a = 10;
        int b = 3;
        int c = a / b;
        int d = a % b;
        System.out.println(c);
        System.out.println(d);
    }
}
```

프로그래밍을 모르는 사람에게 `10 나누기 3`이 얼마냐고 물으면 대부분 `3.3333333...`이라고 대답할 것이다. 하지만 `사탕 10개를 3명에게 나눠주면 어떻게 될까?`라고 물으면 `3개씩 주고 1개가 남는다`라고 말할 것이다. 이처럼 나눗셈은 대상이 무엇이냐에 따라 다르게 처리되며, 프로그래밍에서도 유용하게 사용되는 개념이다.

이를 위해 **정수끼리의 계산 결과는 정수**라는 원칙이 존재하며, 따라서 위의 실행 결과는 c가 3, d가 1이 나오게 된다. 참고로 `%`는 백분율이 아니라 **나머지**를 의미한다. 이를 이용하여 패턴 파악, 숫자 묶음 등 다양한 처리가 가능하며 이는 계산 페이지에서 살펴보도록 한다.
