[Syntax, C++] struct, enum, union을 활용하여 계산기 구현하기

2023. 5. 2. 17:06·Computer Science and Engineering/OOP (Object Oriented Programming)
728x90

pointer, array, struct, enum, enum class...

이 정도만 하면 얼추 C++에서 객체 지향 프로그래밍을 하기 위한 준비는 끝마쳤다고 볼 수 있겠다. class에 관한 syntax는 OOP와 함께 다뤄볼 예정이다.

 

함수와 구조체를 사용하는 이유는 복잡한 반복되는 과정을 효율적으로 처리하기 위함이다. 이번 시간에는 주어진 입력이 정수, 실수, 허수인지를 알아서 분기하여 사칙연산을 수행할 수 있게 하는 계산기를 만들 예정이다. 더하기와 빼기는 비교적 쉬우므로, 곱하기와 나누기 정도만 구현해 보도록 하자.

 

1. 수를 담는 구조체 (타입은 enum으로 분기, union으로 한 수에는 하나의 타입 매칭)

2. 수를 로그에 출력하는 함수

3. 수의 실수 부분(real_component)과 허수 부분(complex_component)을 반환하는 함수

4. 복소수의 크기(magnitude)를 반환하는 함수

3. 두 수의 곱(multiply), 나눗셈(divide) 결과를 반환하는 함수

 

struct

struct number {
	enum number_type { integer, real, complex_num } number_type;
    union {
    	long integer_value,
        double real_value,
        struct {
        	double r, i;
        } complex_value;
    };
};

number의 구조는 해당 수를 분기해 주기 위한 열거형과 수의 유형에 따른 값을 하나만 가질 수 있게 하는 union으로 이루어져 있다.

 

수를 로그에 출력하는 함수

static void print(number const* n) {
	switch (n->number_type) {
	case number::number_type::integer:		cout << n->integer_value; break;
	case number::number_type::real:			cout << n->real_value; break;
	case number::number_type::complex_num:	cout << n->complex_value.r << " + " << n->complex_value.i << "i"; break;
	}
}

수의 타입으로 분기하여 로그에 찍어준다. 복소수는 실수부와 정수부를 나누어 a + bi 꼴로 출력한다.

 

실수부, 허수부 반환 함수

// 실수 부분 반환
static double real_component(number const* n) {
	switch (n->number_type) {
	default:
	case number::number_type::integer:	return n->integer_value;
	case number::number_type::real:		return n->real_value;
	case number::number_type::complex_num:	return n->complex_value.r;
	}
}

// 허수 부분 반환
static double imaginary_component(number const* n) {
	switch (n->number_type) {
	case number::number_type::complex_num:	return n->complex_value.i;
	default:								return 0;
	}
}

우리는 어느 타입의 숫자가 들어와도 계산할 수 있는 코드를 짜야하기 때문에, 허수부가 존재하지 않는 타입의 허수부는 0으로 처리한다.

 

복소수의 크기를 반환하는 함수

static double magnitude(double r, double i) {
	return sqrt(r*r + i*i);
}

복소수의 크기는 복소수의 곱과 나눗셈에서 중요한 역할을 한다. 곱에서는 크기 * 크기가 결과의 크기가 되고, 나눗셈에서는 크기 / 크기가 결과의 크기가 된다.

 

두 수의 곱, 나누셈을 반환하는 함수

static number multiply(number const* a, number const* b) {
	if (a->number_type == number::number_type::complex_num ||
	b->number_type == number::number_type::complex_num) {
		double r1 = real_component(a), i1 = imaginary_component(a),
		r2 = real_component(b), i2 = imaginary_component(b);
		double mag_r = magnitude(r1, i1) * magnitude(r2, i2);
		double a_r = atan2(i1, r1) + atan2(i2, r2);
		number n = {
			.number_type = number::number_type::complex_num,
			.complex_value = { mag_r * cos(a_r), mag_r * sin(a_r) }
		};
		return n;
	} else {
		number n = {
			.number_type = number::number_type::real,
			.real_value = real_component(a) * real_component(b)
		};

		return n;
	}
}

static number divide(number const* dividend, number const* divisor) {
	if (dividend->number_type == number::number_type::complex_num
	|| divisor->number_type == number::number_type::complex_num) {
		double r1 = real_component(dividend), i1 = imaginary_component(dividend),
			r2 = real_component(divisor), i2 = imaginary_component(divisor);
		double a_r = atan2(i1, r1) - atan2(i2, r2);
		double mag_r = magnitude(r1, i1) / magnitude(r2, i2);
		number n = { .number_type = number::number_type::complex_num,
			.complex_value = { mag_r * cos(a_r), mag_r * sin(a_r) } };
		return n;
	} else {
		number n = { .number_type = number::number_type::real,
			.real_value = real_component(dividend) / real_component(divisor) };
		return n;
	}
}

복소평면의 r, i 축을 통해 탄젠트 값을 알 수 있어 arctan로 각도를 구하고, 다시 cos와 sin을 이용해 계산한 값을 복소수로 반환해 준다.

 

 

728x90
저작자표시 (새창열림)

'Computer Science and Engineering > OOP (Object Oriented Programming)' 카테고리의 다른 글

[OOP, C++] Class 기초 - 선언, 초기화, 사용  (0) 2023.05.22
[Syntax, C++] Reference(&) - 참조란?  (0) 2023.05.22
[Syntax, C++] struct를 활용하여 다각형의 둘레의 길이 구하기  (1) 2023.04.27
[Syntax, C++] struct, enum class를 활용하여 날짜(D - day) 계산하기  (0) 2023.04.27
[Syntax, C++] Array에서의 Pointer  (1) 2023.03.21
'Computer Science and Engineering/OOP (Object Oriented Programming)' 카테고리의 다른 글
  • [OOP, C++] Class 기초 - 선언, 초기화, 사용
  • [Syntax, C++] Reference(&) - 참조란?
  • [Syntax, C++] struct를 활용하여 다각형의 둘레의 길이 구하기
  • [Syntax, C++] struct, enum class를 활용하여 날짜(D - day) 계산하기
100두산
100두산
출발하게 만드는 힘이 동기라면, 계속 나아가게 만드는 힘은 습관이다.
  • 100두산
    정상에서 보자 ✈️
    100두산
  • 전체
    오늘
    어제
    • 분류 전체보기 (126)
      • Life (6)
        • living (1)
      • Research (6)
      • AI (20)
      • Dev (45)
        • iOS (28)
        • Web (4)
        • flutter (9)
        • etc (4)
      • PS (Problem Solving) (23)
      • Computer Science and Engine.. (21)
        • Data Structures and Algorit.. (13)
        • OOP (Object Oriented Progra.. (8)
      • etc (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    D3
    알고리즘
    c++
    xcode
    PS
    SKTelecom
    ios
    Python
    백트래킹
    swift
    오블완
    TIP
    SKT
    백준
    자료구조
    AI
    티스토리챌린지
    Challenger
    BOJ
    파이썬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.2
100두산
[Syntax, C++] struct, enum, union을 활용하여 계산기 구현하기
상단으로

티스토리툴바