Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

부스트 라이브러리를 활용한 고급 C++ 프로그래밍

C++ 부스트(Boost) 라이브러리는 다양한 분야에서 폭넓게 활용되는 강력한 오픈소스 라이브러리입니다. 특히 표준 C++ 타입만으로는 표현하기 어려운 매우 큰 숫자를 다룰 때 그 진가를 발휘합니다. 예를 들어 부스트를 사용하면 64비트를 훌쩍 넘는 거대한 정수도 C++에서 자유롭게 계산할 수 있습니다.

이번 글에서는 부스트 라이브러리의 대표적인 기능인 다중 정밀도(multiprecision) 연산을 세 가지 예제를 통해 살펴보겠습니다.

1. int128_t로 두 개의 거대한 수 곱하기

부스트의 multiprecision 라이브러리는 int128_t, int256_t, int1024_t 같은 고정폭 대형 정수 타입을 제공합니다. 이를 활용하면 최대 1024비트까지의 정밀도를 손쉽게 확보할 수 있습니다.

다음 예제는 long long 범위를 벗어나는 두 개의 거대한 수를 int128_t 타입으로 곱하는 코드입니다.

#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
using namespace std;

int128_t large_product(long long n1, long long n2) {
    int128_t ans = (int128_t)n1 * n2;
    return ans;
}

int main() {
    long long num1 = 98745636214564698;
    long long num2 = 7459874565236544789;
    cout << "Product of " << num1 << " * " << num2 << " = "
         << large_product(num1, num2) << endl;
}

실행 결과

Product of 98745636214564698 * 7459874565236544789 =
736630060025131838840151335215258722

2. cpp_int로 임의 정밀도 정수 다루기

임의 정밀도(Arbitrary Precision) 데이터 타입인 cpp_int를 사용하면 정밀도를 미리 지정할 필요가 없습니다. cpp_int는 실행 시간에 필요한 만큼 정밀도를 자동으로 할당하므로, 50!처럼 자릿수가 기하급수적으로 커지는 연산도 문제없이 처리할 수 있습니다.

다음 예제는 cpp_int를 이용해 50 팩토리얼을 계산합니다.

#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
using namespace boost::multiprecision;
using namespace std;

cpp_int large_fact(int num) {
    cpp_int fact = 1;
    for (int i = num; i > 1; --i)
        fact *= i;
    return fact;
}

int main() {
    cout << "Factorial of 50: " << large_fact(50) << endl;
}

실행 결과

Factorial of 50:
30414093201713378043612608166064768844377641568960512000000000000

3. 다중 정밀도 부동소수점으로 고정밀 실수 연산하기

부스트의 다중 정밀도 부동소수점 타입을 사용하면 소수점 이하 50자리 또는 100자리의 정밀도를 얻을 수 있습니다. 각각 cpp_dec_float_50과 cpp_dec_float_100 타입을 사용하면 됩니다.

다음 예제는 반지름이 2.43인 원의 넓이를 float, double, 그리고 cpp_dec_float_50 세 가지 타입으로 각각 계산하여 결과의 정밀도 차이를 비교합니다.

#include <iostream>
#include <iomanip>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/math/constants/constants.hpp>
using boost::multiprecision::cpp_dec_float_50;
using namespace std;

template<typename T>
inline T circle_area(T r) {
    // pi는 미리 정의된 상수입니다.
    using boost::math::constants::pi;
    return pi<T>() * r * r;
}

int main() {
    float f_rad = 243.0 / 100;
    float f_area = circle_area(f_rad);

    double d_rad = 243.0 / 100;
    double d_area = circle_area(d_rad);

    cpp_dec_float_50 rad_mp = 243.0 / 100;
    cpp_dec_float_50 area_mp = circle_area(rad_mp);

    cout << "Float: "
         << setprecision(numeric_limits<float>::digits10) << f_area << endl;

    cout << "Double: "
         << setprecision(numeric_limits<double>::digits10) << d_area << endl;

    cout << "Boost Multiprecision Res: "
         << setprecision(numeric_limits<cpp_dec_float_50>::digits10)
         << area_mp << endl;
}

실행 결과

Float: 18.5508
Double: 18.5507904601824
Boost Multiprecision Res:
18.550790460182372534747952560288165408707655564121

마무리

이처럼 부스트 라이브러리를 활용하면 표준 C++ 타입의 한계를 뛰어넘는 고정밀 산술 연산을 간단하게 구현할 수 있습니다. 암호화, 과학 시뮬레이션, 금융 계산처럼 정밀도가 중요한 분야라면 boost::multiprecision 라이브러리를 적극적으로 활용해 보시기 바랍니다.