03-2 숫자

윤혜민·박현규 · 13 / 30

파이썬에서 숫자는 정수, 실수, 복소수로 구분합니다. 다만 복소수는 거의 쓰일 일이 없어 이 책에서는 다루지 않습니다. 정수는 말 그대로 소수점이 없는 수를 이야기하고, 실수는 소수점이 있는 수를 이야기합니다.

우리가 수학 시간에 배운 그대로입니다. 숫자의 개념은 이것으로 끝입니다. 다만 파이썬에서 숫자를 다루는 방식은 조금 복잡합니다. 프로그래밍 세계에서는 값을 다루는 방식이 매우 중요합니다. 하나씩 천천히 알아보고 연습해봅시다.

숫자를 변수에 저장하기

이제는 좀 질릴 수도 있습니다. 정수를 변수에 저장하는 방법을 다시 살펴봅시다.

>>> age = 25
>>> print(age) # 25

이제는 별로 대단할 것 없는 사용 방식입니다. 다만 여기서 알아두고 넘어갈 내용이 있다면 파이썬은 여러분이 코드를 이렇게 작성하면 25라는 값을 보고 알아서 적절한 판단을 통해 값을 정수로 생각하여 저장한다는 겁니다. 만약 여러분이 코드를 이렇게 작성했다면...

>>> age = 25.0
>>> print(age) # 25.0

파이썬은 age에 정수가 아니라 실수를 담습니다. 숫자를 변수에 저장할 때는 이 콘셉트가 아주 중요합니다. 왜냐하면 나중에 계산을 하는 방식에 영향을 미치기 때문입니다. 아무튼 지금은 '아~ 값에 따라서 파이썬은 숫자를 다르게 취급하는 구나' 정도만 감을 잡고 넘어가면 됩니다.

얼마나 큰 수를 저장할 수 있을까?

그러면 파이썬은 얼마나 큰 수를 저장할 수 있을까요? 여러분이 사용하는 파이썬 버전 3에서는 메모리 크기만 허용한다면 무제한으로 큰 수를 저장할 수 있습니다. 하지만 암묵적인 룰로 호환성을 위해 32비트와 64비트 시스템에서 다음과 같은 암묵적인 한계치를 둡니다. 더 큰 수를 쓸 수 있지만 이보다 큰 수를 쓰지 말라는 뜻이죠.

  1. 32비트 시스템 : 2³¹-1

  2. 64비트 시스템 : 262-1

아마 대부분 64비트 시스템 운영체제를 쓰고 있을 겁니다. 그래서 파이썬 버전 3에서 가장 큰 수를 저장한다면 263-1이겠네요. 이 수가 얼마나 큰 수인지 짐작하기 어려울 겁니다. 실제로 계산하면 얼마일까요? 다음 코드의 결괏값을 살펴봅시다.

>>> import sys
>>> sys.maxsize

9223372036854775807

>>> 2**63-1

9223372036854775807

파이썬 인터랙티브 셸에서 계산한 2**63-1에서 **는 거듭제곱 연산자입니다. 그래서 2**63은 263과 같습니다. 계산한 값은 읽기도 어렵습니다. 9223조 3720억 3685만 4775입니다. 앞에서 이보다 더 큰 수를 쓸 수 있지만 암묵적으로 여기까지만 쓰자라고 한 수가 이 정도로 큰 수인 거죠. 이렇게 파이썬은 매우 큰 수를 다룰 수 있습니다. 물론 여러분이 이보다 큰 수를 다룰 일은 거의 없을 겁니다.

숫자 종류 확인해보기

아까 앞에서 파이썬이 수를 저장할 때 무엇으로 취급할지 값을 보고 정한다고 했습니다. 그러면 그 수를 파이썬에서 무엇으로 취급하는지는 어떻게 알 수 있을까요? 검사할 내용을 type(12)와 같이 적어 실행하면 됩니다. 이렇게 소괄호 사이에 뭔가를 넣어서 실행하면 특정 작업을 하는 문법을 함수라고 합니다. 이미 앞에서 print( ) 함수도 자주 사용했습니다. 함수의 개념은 나중에 배울 테니 우선은 숫자 데이터를 파이썬이 어떻게 취급하는지 확인하는 것에만 집중합시다.

정수는 int

type(12)의 실행 결과는 다음 코드의 결과에서 보듯 <class 'int'>입니다. class라는 표현과 <와 >로 감싼 표현이 좀 어색하지만 'int'라는 표현만 보면 '12라는 숫자는 파이썬에서 int로 생각한다' 정도로 볼 수 있습니다. int는 '인트'라고 읽습니다. 정수는 영어로 Integer라고 하는데 여기서 앞글자 3개를 딴 겁니다.

>>> type(12)

<class 'int'>

실수는 float

그럼 type(3.14)의 실행 결과는 무엇일까요? 'float'이네요.

type(3.14)

<class 'float'>

음 이상합니다. 실수는 영어로 real number거든요. 그렇다면 왜 실수를 float이라 부를까요? 그 이유는 실수를 컴퓨터 세계에서 표현하기 위해 사용하는 기법의 이름이 부동소수점이기 때문입니다. 부동소수점은 영어로 floating point입니다. 부동이라는 단어의 뜻 자체가 '부유하다', '떠다닌다'라는 뜻인데 실수를 표현할 때 가수(mantissa) × 밑수^지수로 표현하는 방식을 보고 떠올린 아이디어입니다. 예를 들어 123.45는 가수(1.2345) × 밑수(10)^지수(2) 방식으로는 다음과 같이 표현할 수 있습니다.

123.45와 1.2345 × 10²는 같습니다. 12.345 × 101도 같고요. 이렇게 소수점이 움직여도 10의 거듭제곱을 적절히 곱하면 같은 수를 표현할 수 있습니다. 이런 모습을 보니 둥둥 떠다닌다고 생각할 만합니다. 그래서 실수에 floating point라는 이름을 붙인 겁니다.

복소수는 complex

파이썬에서 복소수는 3 + 4j와 같이 소문자 j를 사용하여 나타냅니다. 수학에서는 i를 사용하지만 파이썬에서는 j를 사용하는 점이 다릅니다. type(3 + 2j)의 결과를 보면 'complex'네요. 복소수는 여러분이 전문 분야에서 일하지 않는 이상 거의 쓸 일이 없습니다. 간단하게 확인만 하고 넘어갑시다.

>>> type(4 + 3j)

<class 'complex'>

파이썬에서의 숫자의 종류를 모두 확인해보았습니다. 이제는 이 수들을 어떻게 쓰는지 배울 차례네요. 기본적인 사칙연산부터 몫, 나머지 구하기, 거듭제곱 구하기 등 다양한 방법으로 사용하겠습니다.

[연습 01] 기본 사칙연산 해보기

그럼 이제 정수로 할 수 있는 다양한 연산을 하겠습니다. 정수끼리 더하거나 빼거나 곱하면 그 결과는 정수로 나옵니다. 그리고 예상하고 있겠지만 정수와 정수의 나눗셈은 실수로 처리합니다. 다음은 기본 사칙연산입니다.

a = 20
b = 7

print(f"{a} + {b} = {a + b}") # 20 + 7 = 27

print(f"{a} - {b} = {a - b}") # 20 - 7 = 13

print(f"{a} × {b} = {a * b}") # 20 × 7 = 140

print(f"{a} ÷ {b} = {a / b}") # 20 ÷ 7 = 2.857142857142857

그렇다면 정수와 실수의 덧셈은 어떨까요? 결과를 정수로 보여줄까요? 실수로 보여줄까요?

a = 20
b = 12.1

print(f"{a} + {b} = {a + b}") # 20 + 12.1 = 32.1

결과는 실수입니다. 이렇게 정수와 실수를 함께 계산하면 결과는 언제나 실수가 나옵니다. 그리고 나누기는 정수끼리 나눠도 결과가 실수입니다.

print(5 + 2.5) # 7.5

print(10 - 3.2) # 6.8

print(4 * 1.5) # 6.0

print(15 / 3) # 5.0 (정수끼리 나누기도 실수 결과)

print(20 / 2.5) # 8.0

특히 4 곱하기 1.5를 한 결과가 6이 아니라 6.0인 점에 주목하기 바랍니다. 사람의 생각으로는 6이나 6.0이나 같으니 6으로 표현하려는 경향이 있지만 컴퓨터 세계에서는 최대한 넓은 범주의 계산을 처리하기 위해 6.0으로 처리합니다.

[연습 02] 몫, 나머지 연산해보기

다음은 몫과 나머지 연산입니다. 몫은 // 연산자로 계산하고 나머지는 % 연산자로 구합니다. 몫과 나머지 연산은 조금 비중 있게 연습하겠습니다. 왜냐하면 짝수 홀수 판별, 자릿수 분리와 같이 꽤 실용적인 곳에서 자주 쓰이기 때문입니다. 실질적인 예제로 충분히 연습해봅시다. 짝수 홀수 판별은 2로 나눈 나머지가 0인지 아닌지만 판별하면 됩니다. 2로 나눠서 나머지가 0이면 짝수, 나머지가 0이 아니면 홀수일 겁니다.

number = 17
if number % 2 == 0:
print(f"{number}는 짝수")
else:

print(f"{number}는 홀수") # 여기가 출력

자릿수 분리는 1의 자리는 10으로 나눈 나머지로 쉽게 얻을 수 있습니다. 10의 자리는 10으로 나눈 몫을 다시 10으로 나눈 나머지를 구하면 됩니다. 100의 자리는 100으로 나눈 몫입니다.

[Note] 물론 반복문을 활용한 더 스마트한 방법이 있지만 지금은 반복문을 배운 상태가 아니므로 이 정도의 연습만 해보고 넘어가겠습니다.

number = 123
ones = number % 10 # 1의 자리는 10으로 나눈 나머지(%)

print(f"일의 자리: {ones}") # 일의 자리 : 3

tens = (number // 10) % 10 # 10의 자리는 10으로 나눈 몫(//)을 10으로 나눈 나머지(%)

print(f"십의 자리: {tens}") # 십의 자리 : 2

hundreds = number // 100 # 100의 자리는 100으로 나눈 몫(//)

print(f"백의 자리: {hundreds}") # 백의 자리 : 1

# 최종 출력(f-string 사용)

print(f"분리된 숫자: {hundreds}, {tens}, {ones}") # 분리된 숫자: 1, 2, 3

[연습 03] 거듭제곱 연산해보기

거듭제곱 연산도 해봅시다. 거듭제곱은 의미 있는 계산을 하기보다는 문법을 확인하는 수준으로 연습하겠습니다.

[Note] 사실 거듭제곱 연산을 현재 의미 있는 코드로 연습하기에는 좀 무리가 있습니다.

# 거듭제곱 연산자 **를 사용하여 2의 3제곱 계산하기
base = 2
exponent = 3
result = base ** exponent

print(f"{base}의 {exponent}제곱: {result}") # 2의 3제곱: 8

숫자는 이 정도 공부했으면 기초를 뗄 정도로는 공부했다고 할 수 있습니다. 이제 조금 더 중요한 자료형인 문자열을 알아보러 가봅시다. 문자열에서 할 이야기가 많습니다.