파이썬(Python)에서는 복잡한 수학 개념도 객체 지향 프로그래밍으로 깔끔하게 구현할 수 있습니다. 이번 글에서는 복소수(Complex Number)를 표현하는 클래스를 직접 정의하고, 아래와 같은 연산 메서드를 구현해 보겠습니다.
- add() — 두 복소수의 덧셈
- sub() — 두 복소수의 뺄셈
- mul() — 두 복소수의 곱셈
- div() — 두 복소수의 나눗셈
- mod() — 복소수의 크기(절댓값, 모듈러스) 계산
복소수는 일반적으로 (a + bi) 형태로 표현됩니다. 여기서 a는 실수부(real part), b는 허수부(imaginary part), i는 허수 단위입니다. 두 개의 복소수를 준비한 뒤, 위 연산들을 하나씩 수행해 보겠습니다.
핵심 아이디어는 연산자 오버로딩(Operator Overloading)입니다. 클래스 내부에서 __add__(), __sub__(), __mul__(), __truediv__() 등의 매직 메서드를 재정의하면 +, -, *, / 연산자를 복소수 객체에 그대로 사용할 수 있습니다. 또한 __str__() 메서드를 오버로딩하면 복소수를 사람이 읽기 쉬운 형태로 출력할 수 있습니다.
예를 들어 입력이 c1 = 2+3i, c2 = 5-2i라면 출력 결과는 다음과 같습니다.
(7.00 + 1.00i), (-3.00 + 5.00i), (16.00 + 11.00i), (0.14 + 0.66i), 3.61, 5.39
문제 해결 접근 방식
이 문제는 다음 순서로 해결할 수 있습니다.
- 실수부
re와 허수부im을 속성으로 갖는Complex클래스를 정의합니다. __add__(o): 새로운 Complex 객체를(re + o.re, im + o.im)값으로 생성해 반환합니다.__sub__(o): 새로운 Complex 객체를(re - o.re, im - o.im)값으로 생성해 반환합니다.__mul__(o): 새로운 Complex 객체를(re × o.re - im × o.im, re × o.im + im × o.re)값으로 생성해 반환합니다.__truediv__(o): 분모m = o.re² + o.im²을 먼저 계산한 후,((re × o.re + im × o.im) / m, (im × o.re - re × o.im) / m)값을 갖는 새로운 객체를 반환합니다.mod():sqrt(re² + im²), 즉 실수부 제곱과 허수부 제곱의 합에 대한 제곱근을 반환합니다.__str__()을 오버로딩하여 출력 형식을 지정합니다.- 허수부가 0이면 실수부만 소수점 둘째 자리까지 반환합니다.
- 실수부가 0이면 허수부만 소수점 둘째 자리까지 반환합니다.
- 허수부가 음수면
re - |im|i형태로 반환합니다. - 그 외의 경우
re + im i형태로 반환합니다.
구현 예제
아래 코드를 통해 실제 동작을 더 잘 이해할 수 있습니다.
from math import sqrt
class Complex:
def __init__(self, real, imag):
self.re = real
self.im = imag
def __add__(self, o):
return Complex(self.re + o.re, self.im + o.im)
def __sub__(self, o):
return Complex(self.re - o.re, self.im - o.im)
def __mul__(self, o):
return Complex(self.re * o.re - self.im * o.im,
self.re * o.im + self.im * o.re)
def __truediv__(self, o):
m = o.re * o.re + o.im * o.im
return Complex((self.re * o.re + self.im * o.im) / m,
(self.im * o.re - self.re * o.im) / m)
def __str__(self):
if self.im == 0:
return '%.2f' % self.re
if self.re == 0:
return '%.2fi' % self.im
if self.im < 0:
return '%.2f - %.2fi' % (self.re, -self.im)
else:
return '%.2f + %.2fi' % (self.re, self.im)
def mod(self):
return sqrt(self.re * self.re + self.im * self.im)
def solve(comp1, comp2):
print(comp1 + comp2)
print(comp1 - comp2)
print(comp1 * comp2)
print(comp1 / comp2)
print('%.2f' % comp1.mod())
print('%.2f' % comp2.mod())
comp1 = Complex(2, 3)
comp2 = Complex(5, -2)
solve(comp1, comp2)입력
comp1 = Complex(2, 3) comp2 = Complex(5, -2)
출력 결과
7.00 + 1.00i -3.00 + 5.00i 16.00 + 11.00i 0.14 + 0.66i 3.61 5.39
마무리
이처럼 파이썬의 연산자 오버로딩을 활용하면 복소수와 같은 수학적 개념도 직관적인 문법으로 다룰 수 있습니다. 참고로 파이썬은 기본 내장 타입인 complex도 제공하므로, 실무에서는 (2+3j)처럼 간단히 복소수를 생성할 수 있습니다. 하지만 연산자 오버로딩 원리를 학습하거나 커스텀 동작이 필요한 경우에는 이번 예제처럼 클래스를 직접 정의하는 것이 큰 도움이 됩니다.