본문 바로가기

정수 자료형

1. 정수란?

정수는 0과 양의 정수, 음의 정수를 모두 포함하는 수를 말합니다. 파이썬에서 정수는 int라는 이름으로 표현됩니다.

파이썬의 int는 다른 언어와 달리 크기 제한이 없습니다. 메모리가 허용하는 한 얼마든지 큰 정수를 다룰 수 있습니다.

1.1 정수 타입의 변수 생성

x = 10
y = -5
z = 0
print(type(x), type(y), type(z))

이 예제에서 x, y, z는 각각 10, -5, 0이라는 정수 값을 가지게 됩니다. 파이썬에서는 소수점이 있으면 정수로 구분하지 않으니 이를 주의해주세요. 10과 10.0은 다른 타입입니다.

1.2 정수의 사칙연산

정수는 기본적인 산술연산을 지원합니다. 이 챕터에서는 간단한 사칙연산만 해보도록 하겠습니다. 값을 바꾸어서 실행해보세요.

1.2.1 덧셈

x = 10
y = 20 # 음수도 넣어보세요.
result = x + y
print(result) # 출력 : 30

1.2.2 뺄셈

x = 10
y = 20 # 음수도 넣어보세요.
result = x - y
print(result) # 출력 : -10

1.2.3 곱셈

x = 10 # 음수도 넣어보세요.
y = 20 # 음수도 넣어보세요.
result = x * y
print(result) # 출력 : 200

1.2.4 나눗셈

나눗셈은 두 종류가 있습니다. 하나(/)는 나눗셈의 결과를 소수점까지 표시하는 것이고, 다른 하나(//)는 몫만 남기는 것입니다. 두 번째 연산은 정확히는 '내림 나눗셈'이라 음수에서는 결과가 예상과 다를 수 있습니다. 이 부분은 연산 챕터에서 자세히 다룹니다. 아래 코드를 실행시켜보세요.

x = 10
y = 20
result1 = x / y
result2 = x // y
print(result1, result2) # 출력

2. 진수

Python에서는 10진수 외에도 2진수, 8진수, 16진수로 정수를 표현할 수 있습니다.

진수접두사구성 숫자예시10진수 변환
2진수0b0, 10b1106
8진수0o0-70o1513
10진수없음0-92626
16진수0x0-9, A-F0x1a26

아래 10진수와 2진수가 표현되는 방법을 기술하였습니다.

# 10진수 731 이라는 숫자는
# (7 * 10^2) + (3 * 10^1) + (1 * 10^0)이며
# 이는 10진수로 731입니다.

# 2진수  110 이라는 숫자는
# (1 * 2^2) + (1 * 2^1) + (0 * 2^0)이며
# 이는 10진수로 6입니다.

x = 731
y = 0b110
print(x, y)

2진수 연산은 알고리즘 문제로 간혹 출제됩니다. 16진수는 컴퓨터에서 색 표현으로 많이 사용합니다. #000000은 검은색이고, #ffffff는 흰색입니다. 8진수는 거의 사용되지 않습니다. 진수 변환이 실무에서 자주 사용되는 개념은 아니기 때문에, 해당 내용은 실제 프로젝트를 진행하며 필요할 때 찾아보시는 것을 권합니다.

2.1 2진수 (Binary)

2진수는 0과 1로만 구성되며, Python에서는 숫자 앞에 0b를 붙여서 2진수로 표현합니다.

x = 0b110
print(x)
print(type(x))

이 예제에서 x는 2진수 110을 10진수로 변환하여 6이 출력됩니다. type(x)는 <class 'int'>로, x의 데이터 타입이 정수임을 확인할 수 있습니다.

2.2 8진수 (Octal)

8진수는 0부터 7까지의 숫자로 구성되며, Python에서는 숫자 앞에 0o를 붙여서 8진수로 표현합니다.

x = 0o15
print(x)
print(type(x))

이 예제에서 x는 8진수 15를 10진수로 변환하여 13이 출력됩니다. type(x)는 <class 'int'>로, x의 데이터 타입이 정수임을 확인할 수 있습니다.

2.3 16진수 (Hexadecimal)

16진수는 0부터 9까지의 숫자와 A(10)부터 F(15)까지의 알파벳으로 구성되며, Python에서는 숫자 앞에 0x를 붙여서 16진수로 표현합니다.

x = 0x1a
print(x)
print(type(x))

이 예제에서 x는 16진수 1a를 10진수로 변환하여 26이 출력됩니다. type(x)는 <class 'int'>로, x의 데이터 타입이 정수임을 확인할 수 있습니다.

2.4 진수 변환 함수

Python에서는 bin(), oct(), hex() 함수를 사용하여 10진수를 각각 2진수, 8진수, 16진수로 변환할 수 있습니다.

x = 26
print(bin(x))
print(oct(x))
print(hex(x))

이 예제에서 x는 26이고, bin(x)는 '0b11010', oct(x)는 '0o32', hex(x)는 '0x1a'를 출력합니다. 이렇게 변환된 값은 int 내장함수(built-in-function)을 사용하여 10진수로 다시 변환할 수 있습니다.

b = int('0b11010', 2)
o = int('0o32', 8)
h = int('0x1a', 16)
print(b, o, h)

출력값은 모두 26입니다.

3. 메서드(Method)

메서드는 특정 자료형(정수, 실수, 문자열, 리스트 등)이 가지고 있는 고유한 기능입니다. 예를 들어, 문자열 자료형은 문자열을 대문자로 변환하는 기능을 가지고 있습니다. 이러한 기능을 수행하는 함수를 메서드라고 부릅니다.

x = 'hello'
print(x.upper()) # 출력 : HELLO, 여기서 upper()는 메서드입니다.

그러나 숫자 자료형에서 사용할 수 있는 메서드는 많지 않으며, 실제로 자주 사용되지도 않습니다. 따라서 이후에 다룰 float와 complex 자료형에서는 메서드를 자세히 다루지 않겠습니다.

x = 5
print(dir(5))

예를 들어, 위 출력된 메서드 중 bit_count메서드를 살펴보도록 하겠습니다. 이 메서드는 파이썬 3.10부터 추가되었기 때문에 그 이전 버전에서는 목록에 보이지 않습니다.

x = 5
x.bit_count() # 출력 : 2, 101 -> 1이 두개 2
x = 4
x.bit_count() # 출력 : 1, 100 -> 1이 한개 1

5는 2진수로 표현했을 때 101이고, 4는 2진수로 표현하면 100입니다. 여기서 1의 개수를 카운팅한 것입니다.

메서드를 모두 암기할 필요는 없습니다. 평생 한 번도 사용하지 않는 메서드도 다수입니다. 다만 한 번은 전체 목록으로 살펴볼 필요가 있습니다. 어떤 메서드가 있다는 것을 알고 있다면, 필요할 때 찾아서 사용할 수 있습니다.

4. 인티저 인터닝

파이썬은 다른 언어에 비해 느린 속도를 극복하기 위해 버전 업데이트마다 다양한 노력을 기울여 왔습니다. 그 중 하나로, 파이썬은 메모리 효율을 위해 자주 사용되는 정수를 미리 메모리에 저장(integer interning)해두고 있습니다. 이렇게 저장된 정수가 나중에 혼란을 줄 수 있기에 여기서 설명하고자 합니다.

# -5 ~ 256
x = 256
y = 256

print(id(x), id(y)) # 출력 : 138041748299984 138041748299984

위 코드에서 x와 y는 같은 값을 가지고 있습니다. 일반적으로 id(x)와 id(y)는 다른 값을 가져야 합니다. 아래 그림처럼요. 이는 대부분의 언어와 파이썬에서도 마찬가지입니다. 하지만 여기서 x가 가리키고 있는 값이 256이기 때문에 별도의 공간을 생성하지 않습니다. 이 경우가 특수한 경우라는 점을 기억해 주세요.

두 변수의 id를 출력하면 같은 값이 나옵니다. 이는 두 변수가 같은 메모리 주소를 가리키고 있다는 의미입니다. 출력되는 주소값 자체는 실행 환경과 실행 시점에 따라 매번 다르므로, 두 값이 서로 같은지만 확인해주세요. 이처럼 메모리에 미리 적재되는 숫자의 범위는 -5부터 256까지입니다. 이 범위에 해당하는 숫자는 아래 그림과 같이 표현할 수 있습니다.

하지만 이 범위를 벗어나면 아래와 같은 그림이 됩니다. 이는 id 값이 다른 것으로 확인할 수 있습니다. 위 예제 코드에서 x와 y의 값을 1000으로 변경해 보면 두 값의 id가 다르게 나오는 것을 확인할 수 있습니다. 다만 위니북스에서는 다른 실행 결과가 나오기 때문에 실행 버튼을 활성화하지 않았습니다. 구글 코랩에서 직접 확인해 보시기 바랍니다.

# -5 ~ 256
x = 1000
y = 1000

print(id(x), id(y))

기본적으로 위와 같이 변수가 생성된다는 사실과 예외 사항을 기억해 주세요. 그렇지 않으면 이 개념이 나중에 크게 혼란을 줄 수 있습니다.

다시 한 번 강조하자면, 변수에 값을 할당하면 예외 사항이 있지만 기본적으로는 서로 다른 메모리 주소를 가집니다.

인티저 인터닝의 범위는 -5 ~ 256이지만, 이 범위 밖에서도 두 변수가 같은 id를 가지는 경우가 있습니다. .py 파일 하나에 x = 1000과 y = 1000을 나란히 적으면 컴파일 단계에서 두 리터럴이 하나의 상수로 합쳐져 같은 객체를 가리키게 됩니다. 셀 단위로 실행되는 코랩과 결과가 달라지는 이유가 여기에 있습니다.