정수

정수

정수는 소수점이 없는 숫자를 말한다. 자세한 저장 원리는 정수의 저장 원리 부분을 참고한다. 정수를 이용할 때 알아야 할 내용들은 다음과 같다.

  • 정수는 여러 종류가 있으며, 각각의 형태 마다 범위가 다르다.

  • 정수는 순환형 구조를 가진다.

  • 정수의 연산 결과는 정수이다.

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

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

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

아메리카노 354mL 주세

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

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

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

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

아메리카노 주세요

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

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

  • 정수를 표현하기 위해 1byte, 2byte, 4byte, 8byte의 크기에 해당하는 단위를 사용하기로 약속한다.

  • 크기를 매번 이야기하기 힘들기 때문에 별칭을 붙여 각각 byte, short, int, long이라고 부른다.

  • 정수 데이터가 크기와 관련된 표기 없이 존재한다면 기본값인 int로 생각한다.

정수 예제 1

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

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

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);
    }
}

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

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

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

관련 기사 링크 : 연합뉴스 기사

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

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

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이 나오게 된다. 참고로 %는 백분율이 아니라 나머지를 의미한다. 이를 이용하여 패턴 파악, 숫자 묶음 등 다양한 처리가 가능하며 이는 계산 페이지에서 살펴보도록 한다.

Last updated