본문 바로가기

진리는어디에/Python

[Python] 변수 #8 파이썬 정수는 Overflow가 없다?

이번 포스트는 파이썬 변수 시리즈의 마지막 강의로 시스템을 꽤 깊이 있게 들여다볼 예정이다. 굳이 시스템에 대해 깊이 있는 이해가 필요 없거나 궁금하지 않은 분은 파이썬의 정수는 Overflow가 없다는 것만 기억하고 이번 포스트를 건너뛰어도 파이썬 프로그램밍을 하는 대부분의 경우 무리가 없다. 하지만 파이썬에 대해 보다 깊은 이해를 하고 싶은 분이라면 이번 포스트르 꼭 보도록 하자.

목차

  1. 파이썬 변수의 소개
  2. 변수의 타입
  3. 변수의 다양한 정보 확인
  4. ctype 모듈을 활용한 변수의 정보 확인
  5. == 와 is 연산자
  6. mutable 변수와 immutable 변수
  7. 변수의 삭제
  8. >> 파이썬 정수는 Overflow가 없다?

Overflow란?

프로그래밍에서 Overflow란 특정 값이 너무 커서 메모리에 담지 못하는 경우를 말한다. 예를 들어 C/C++의 경우 정수형 변수는 4바이트 메모리 공간을 할당 받는데 이는 -2,147,483,648 ~ 2,147,483,647 사이의 값을 가진다. 만일 저 값을 넘어가는 경우 해당 값을 제대로 표현해주지 못하게 된다.

하지만 파이썬 정수는 Overflow가 발생하지 않는다.

파이썬 정수형 변수의 구조

이해를 돕기 위해 먼저 아래의 예제를 살펴 보자.

import sys

n1 = 10
n2 = 10000000000 # 0이 10개
n3 = 100000000000000000000 # 0이 20개
n4 = n2 * n3

print('value of n1:' + str(n1))
print('value of n2:' + str(n2))
print('value of n3:' + str(n3))
print('value of n4:' + str(n4))

print('size of n1:' + str(sys.getsizeof(n1)))
print('size of n2:' + str(sys.getsizeof(n2)))
print('size of n3:' + str(sys.getsizeof(n3)))
print('size of n4:' + str(sys.getsizeof(n4)))

먼저 n1을 보면 10이다. n2는 0이 10개, n3는 0이 20개. 심지어 n4는 n2와 n3의 곱이다. 만일 C/C++, C#, Java와 같은 언어에서 저렇게 썻다가는 overflow가 발생하게 된다. 하지만 위 코드를 실행 시켜 보면 파이썬에서는 아무런 문제 없이 실행 된다.

> python main.py
value of n1:10
value of n2:10000000000
value of n3:100000000000000000000
value of n4:10000000000000000000000000000000000000000
size of n1:28
size of n2:32
size of n3:36
size of n4:44

성능이 더 좋다는 C/C++도 못하는 일을 파이썬은 어떻게 해낼 수 있었을까? 지금 부터 그 원리가 무엇인지 살펴 보자.

Flexible Array

[Python] 파이썬 기초부터 시작하기 - 변수 포스트에서 파이썬 변수를 생성하게 되면 아래와 같은 모양의 구조체가 메모리에 생성 된다고 이야기 했었다.

PyLongObject

파이썬 내부에서 정수 타입을 표현하기 위해 C로 구현된 구조체인데 이름은 PyLongObject다. 특징이 구조체의 마지막 멤버 ob_digit가 단순 정수형 변수가 아닌 배열형태로 되어있다. 이는 C언어의 flexible array라는 기술로써 저장해야 하는 값의 크기에 따라 배열을 키우거나 줄인다.

예를 들어 n2는 0이 10개나 되는 정수로써 4바이트 내에 저장 할 수가 없다. 그런 경우 아래와 같이 ob_digit의 사이즈를 8바이트로 늘려 저장한다. n3의 경우는 8바이트로도 값을 저장 할 수 없기 때문에 다시 배열을 늘려 12바이트에 저장한다. 마지막 n4를 저장하기 위해서는 20바이트가 필요하다. 객체가 현재 얼마만큼의 배열 크기를 가지고 있는지를 관리하기 위해 ob_size에는 현재 배열을 크기를 저장한다.

위 정수의 크기가 커질 수록 저장하는 메모리 사이즈를 늘려감으로써 파이썬은 아무리 큰 정수라 하더라도 overflow 에러를 발생시키지 않는다.

마치며

이상 파이썬 변수에 대해 알아 보았다. 아직 전역 변수, 지역 변수와 같은 개념들을 다루진 않았으나 이는 나중에 함수 관련 강좌를 하면서 다루어 질것이니 조금 기다려주길 바란다.

다음 강의 부터는 파이썬 문자열에서 부터 시작해서 이터레이션, 시퀀스 자료형들에 대해 다루도록 하겠다.

부록 1. 같이 읽으면 좋은 글

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!