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비트 윈도에서 마이크로소프트 기반 빌드 툴의 빌드를 지원

...라고 말은 하지만 가장 큰 목적은 윈도에서 GMP를 쉽게 사용하기 위함이다. GNU 계열 OS는 그냥 GMP 쓰면 된다.




1. 설치 및 환경 설정 #

공식 사이트
http://mpir.org/

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]이 없기 때문이다.


Win32 VS2010 .zip (for use with VS2010 on 32-bit Windows)
Win64 VS2010 .zip (for use with VS2010 on 64-bit Windows)

윈도 비트에 맞는 걸 받아 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



이 글에는 0 개의 댓글이 있습니다.