MPIR로 C++ 고정밀 연산을 해 보자

작성일: 2013-08-28


들어가며

C 환경에서 가장 유명한 오픈소스 고정밀(Multiprecision) 연산 라이브러리는 GNU Multiple Precision Arithmetic Library(GMP)일 것이다. GMP는 리눅스 환경에서 사용하기 간편하지만 윈도우(VC++)환경에서 사용하는 것은 쉽지 않으며 최신 버전에서는 VC++ 환경에서 빌드 가능한 솔루션을 제공하고 있기는 하나 여전히 불편하다. 윈도우(VC++)에서 고정밀 연산 라이브러리를 사용하려고 할 때 MPIR는 훌륭한 대안이다. MPIR는 GMP에서 fork 된 오픈소스 프로젝트이며 대부분의 코드가 GMP으로부터 왔고 추가 오리지널 기여 코드로 구성되어 있다. MPIR 개발자가 말하는 MPIR 프로젝트의 주 목적은 다음과 같다[1].

  • GPU와 멀티 코어 프로세서를 지원하는 병렬 알고리즘 고정밀 연산
  • GMP와의 호환성을 유지 - 따라서 MPIR는 GMP로도 대체될 수 있다.
  • 리눅스, Mac OS, Solaris, 그리고 윈도 빌드 지원을 제공.
  • 32비트, 64비트 윈도에서 마이크로소프트 기반 빌드 툴의 빌드를 지원

...라고 말은 하지만 결국 MPIR의 목적은 프로젝트의 부제 MPIR (GMP Windows fork)와 같이 윈도에서 GMP를 쉽게 사용하기 위함이다. GMP는 전통적으로 GCC, Unix/Linux 환경을 중심으로 발전했다. 반면 MPIR은 Visual Studio/MSVC에서 직접 빌드하기 편리하다는 이점을 제공한다. 따라서 GNU 계열 OS는 그냥 GMP 쓰면 된다.

(2026.10.14 추가)
MPIR은 과거에는 상당히 중요한 고정밀 정수 연산 라이브러리였지만, 2026년 현재는 신규 프로젝트에서 예전만큼 많이 선택되지 않는 편이다. 특히 적극적인 개발과 유지보수가 사실상 중단된 상태라는 점이 크다. 하지만 MPIR이 성능이 떨어지는 건 아니고 오래된 라이브러리지만 지금도 상용 제품 내부에서 계속 활용되고 있는 사례가 있다.

정식 명칭 Multiple Precision Integers and Rationals
출발점 GMP에서 분기(Fork)
최신 정식 버전 3.0.0
최신 정식 버전 출시 2017년
개발 상태 사실상 유지보수 중단
Windows/MSVC 지원 주요 강점
GMP API 호환성 높은 수준의 호환성
신규 프로젝트 추천 제한적



1. 설치 및 환경 설정 #

1.1. 소스 코드 다운로드 #

최신 버전을 받는다. (현재 Stable release MPIR 2.6.0 / November 8, 2012)

1.2. 빌드 #

mpir-2.6.0\build.vc10 디렉토리에서 VC++ 솔루션 mpir.sln을 연다.

사용할 환경에 맞는 프로젝트를 빌드한다. (예: Debug, x64, lib, gc)

Error    17    error MSB3721: The command ""C:\Program Files (x86)\Microsoft 
Visual Studio 11.0\VC\bin\"vsyasm.exe -Xvc -f Win32 -g cv8 -i 
"..\..\mpn\x86_64w\\" -o "Win32\Release\mpn\\" -rnasm 

빌드할 때 위 에러가 발생하면 yasm[2]이 없기 때문이다.
윈도 비트에 맞는 걸 받아 C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\ 에 압축을 해제한다.

1.3. 빌드 완료 #

빌드가 성공하면 mpir-2.6.0\dll\, mpir-2.6.0\lib\에 바이너리(mpir.dll, mpir.lib)가 생성된다.

2. 사용하기 #


Quick Start

모든 C++ 클래스와 함수는 다음 헤더로 사용 가능하다.

#include <gmpxx.h> (또는 #include <mpirxx.h>)

gmpxx.h에서 알 수 있듯 GMP 코드와 완벽히 호환된다.
그리고 다음 클래스에 모든 연산자와 함수가 오버로드되어 있다.

  • mpz_class
  • mpq_class
  • mpf_class

For example.

int
main (void)
{
  mpz_class a, b, c;
    
  a = 1234;
  b = "-5678";
  c = a+b;
  cout << "sum is " << c << "\n";
  cout << "absolute value is " << abs(c) << "\n";
    
  return 0;
}

GMP의 C++ 클래스 오버로딩이 안 된 함수들(gcd 등)은 C++ 클래스를 GMP C 타입으로 바꿔야 하는데 그런 경우 각 클래스 안에 다음 메서드를 쓰면 된다. (mpz_t가 GMP C 타입)

 mpz_t mpz_class::get_mpz_t()

즉, 다음 같은 코딩이 된다.

 mpz_class a, b, c;
 ...
 mpz_gcd (a.get_mpz_t(), b.get_mpz_t(), c.get_mpz_t());

반대의 경우, 클래스는 GMP C 타입으로 클래스를 초기화하거나 명시적인 생성자를 사용하여 할당할 수 있다.

 mpz_t z;
 // ... init and calculate z ...
 mpz_class x(z);
 mpz_class y;
 y = mpz_class (z);

3. 기타 #

MPIR(고정밀 연산 라이브러리)를 Visual Studio 2010에서 빌드 및 기본 사용법
http://pureholic.net/?p=388

Multiple Precision Arithmetic on Windows
http://gladman.plushost.co.uk/oldsite/computing/gmp4win.php



Show Comments