'MPIR'에 해당되는 글 2건

  1. 2013.01.24 C# 에서 xmpir 사용하기
  2. 2013.01.16 윈도우에 MPIR 라이브러리 설치하고 사용하기 2

1. mpir 은 gmp 대신사용하는 (C/C++ 언어용) 긴 자리 수치 처리를 위한 기본 연산 라이브러리이다.

   자리수가 매우 긴 정수, 유리수, 소수점수를 계산할 수 있다.

2. xmpir 은 (C 언어용 긴 자리 수치 라이브러리인) mpir 의 래퍼(wrapper) 이다.

3. xmpir 은  xmpir 다운로드 에서 구할 수 있다.

(주의 사항. dl4windows.dll 파일이 존재하는 폴더의 경로명에 #문자가 있으면 컴파일은 되나 실행 시에 에러에 걸린다. 그 이유는 xmpir 이 dl4windows.dll 파일을 찾을 때 URL 주소를 적용해서 찾기 때문이다.)

 

실행에 필요한 *.dll 파일들은 (현재 경로 또는) 환경변수 PATH 에 결린 경로의 폴더에 존재해야 한다.

  • dl4windows.dll  : 윈도우 계열의 닷넷 에서 실행될 때 xmpir 이 찾는 파일
  • dl4linux.dll  : 리눅스 계열의 mono 에서 실행될 때 xmpir 이 찾는 파일
  • xmpir32.dll : 32 비트 윈도우 또는 리눅스에서 실행될 때 PATH 걸린 폴더에 있어야 하는 파일
  • xmpir64.dll : 64 비트 윈도우 또는 리눅스에서 실행될 때 PATH 걸린 폴더에 있어야 하는 파일
  • src\xmpir,cs : 컴파일할 때 함께 사용되어야 하는 파일

 

demo 폴더에서 demo,cs 컴파일하기

    Prompt> csc demo.cs ..\src\xmpir.cs

 

xmpir 을 이용하는 예제 소스 파일 (파일명: demo.cs)

using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;
class MyClass
{
    [STAThread]
    static void Main(string[] args)
    {
        mpir.mpz_t f = mpir.mpz_init_set_ui(1);
        int i;
        for(i=2; i<=30; i++)
            mpir.mpz_mul_si(f, f, i);
        System.Console.Write("30! = ");
        System.Console.WriteLine(mpir.mpz_get_string(10,f));
        mpir.mpz_clear(f);        
    }
}

 

실행 결과: 30! = 265252859812191058636308480000000

 

Posted by Scripter
,

MPIR 은 Multiple Precision Integers and Rationals 은 줄인 약자로서 C 언어나 C++ 언어로 매우 긴 자리의 수치 연산을 하는 프로그램을 작성할 때 사용되는 라이브러리이다.

참고. 위키피디아의 MPIR 설명

MPIR 은 GMP 처럼 무한 자리 수치 계산을 위한 (GMP 를 대체하는) 기본 라이브러리이다. MPIR 은 정수 계산, 유리수 계산, 부동소수점수 계산은 지원하지만, 복소수 계산은 지원하지 않는다.

MPIR 은 GMP 보다 훨씬 다양한 OS 를 지원하며 CPU 에 최적화 되어있다. MPIR 은 LGPL 3 적작권으로 보호받는 소스 공개 소프트웨어이다. 상업용 패키지에 포함시킬 때는 MPIR 이 GMP 보다 라이센스 면에서 더 자유로운 것 같다.

 

다음은 MPIR 홈페이지에서 소개하는 글의 일부이다.

----------------------------------------------------

About MPIR

MPIR is an open source multiprecision integer (bignum) library forked from the GMP (GNU Multi Precision) project. It consists of much code from past GMP releases, in combination with much original contributed code. A brief introduction can be found here Introduction(French)

MPIR is constructed by a developer and vendor friendly community of professional and amateur mathematicians, computer scientists and hobbyists.

The primary goals of the MPIR project are:

  • To have a developer friendly community.
  • To foster links with hardware and software vendors.
  • Development of parallel algorithms for multiprecision arithmetic including support for GPU's and other multicore processors.
  • To provide build support out-of-the-box for Linux, Apple, Sun and Microsoft Windows systems.
  • To overall license the project with the GNU LGPL license.
  • To maintain full interface support with GMP - MPIR is a drop-in replacement for GMP.
  • Support for building MPIR using Microsoft Visual Studio 2010 for use in both 32-bit and 64-bit versions of Windows.

----------------------------------------------------

MPIR 2.6.0 이 그 이전 버전과 다른 부분은 매우 많겠지만, 우선 눈에 보이는 두 가지만 언급한다면, 하나는 64비트 CPU 와 OS 를 확실하게 지원한다는 것이고, 다른 하나는 Visual Studio 2010 에 더 쉽게 설치된다는 것이다. (하지만 안정적인 면에서는 2.6.0 보다 그 이전 버전이 좋지 않나 생각한다.)

이 글에서는 32 비트 윈도우 XP 에 cygwin 용으로, MinGW 용으로, 그리고 Visual Studio 2010 용으로 각각 빌드하여 설치하고 테스트한 결과를 남겨 두고자 한다.

 

 

1. Visual Studio 2010 에 설치하기

단계 1.  압축을 푼다.

압축 해제돤 것을 모두 폴더 D:\mpir-2.6.0 에 둔 것으로 간주하고 다음 단계를 계속 진행한다.

Visual Studio 2010 용 솔루션 파일 mpir.sln 은 폴더 D:\mpir-2.6.0\build.vc10 에 존재해야 한다.

 

단계 2.  MPIR 2.6.0 설치 과정

Visual Studio 2010 의 메뉴에서 "파일(F)" -> "열기(O)" -> "프로젝트/솔루션(P).." 를 선택하여 파일 D:\mpir-2.6.0\build.vc10\mpir.sln 을 연다.

Visual Studio 2010 의 메뉴에서 "빌드(B)" -> "구성 관리자(O)..." 를 선택한다.

아래의 그림 처럼 세 가지 항목을 선택한다. (체크박스에 체크 확인)

 

 

메뉴에서 "빌드(B)" -> "솔루션 다시 빌드(S)" 를 선택하여 (위에서 처럼) 구성관리자에서 선택햇던 항목들을 모두 빌드한다.

 

단계 3.  빌드 후 확인

dll 파일과 관련 헤더 파일은 폴더 D:\mpir-2.6.0\build.vc10\dll\Win32\Releae 에 생성되고, lib 파일과 관련 헤더 파일은 폴더 D:\mpir-2.6.0\build.vc10\lib\Win32\Releae 에 생성된다.

만일 위의 구성관리자에서 체크된 세 가지 항목을 (Release 대신) Debug 로 선택하였다면, dll 파일과 관련 헤더 파일은 폴더 D:\mpir-2.6.0\build.vc10\dll\Win32\Debug 에 생성되고, lib 파일과 관련 헤더 파일은 폴더 D:\mpir-2.6.0\build.vc10\lib\Win32\Debug 에 생성된다.

Visual Studio 2010 용으로 빌드된 mpir 은 C++ 용 라이브러리 mpirxx.lib 가 추가로 더 생성되지만, dll 파일로는 mpir.dll 만 생성된다. (mpirxx.dll 파일은 별도로 생성되지 않는다.)

 

단계 4.  MPIR 2.6.0 설치 후 테스트

아래세 제시된 C 소스와 C++ 소스를 각각 컴파일하여 실행해본다. (컴파일 명령은 각 소스의 주석문 참조)

 

 

2. cygwin 에 설치하기

단계 1.  압축을 푼다.

 

단계 2.  MPIR 2.6.0 설치 순서

아래의 configure 명령 중에 옵션 --enable-cxx CXXFLAGS=-g 이 중요하다. 이 옵션이 없으면 mpir 의 C++ 용 헤더 파일과 라이브러리가 설치되지 않는다. (Visual Studio 2010 용으로 빌드하는 것 보다는 시간이 훨씬 더 오래 걸린디.)

$ ./configure --prefix=/usr --enable-cxx CXXFLAGS=-g
$ make
$ make check
$ make install
$ make clean

설치가 성공적으로 끝나면 헤더 파일은 /usr/include 폴더에  라이브러리 파일은 /usr/lib 폴더에 생성된다.

 

 

단계 3.  MPIR 2.6.0 설치 후 테스트

아래세 제시된 C 소스와 C++ 소스를 각각 컴파일하여 실행해본다. (컴파일 명령은 각 소스의 주석문 참조)

 

 

3. MinGW 에 설치하기

단계 1.  압축을 푼다.

 

단계 2.  MPIR 2.6.0 설치 순서

아래의 configure 명령 중에 옵션 --enable-cxx CXXFLAGS=-g 이 중요하다. 이 옵션이 없으면 mpir 의 C++ 용 헤더 파일과 라이브러리가 설치되지 않는다. (Visual Studio 2010 용으로 빌드하는 것 보다는 시간이 훨씬 더 오래 걸린디.)

$ ./configure --prefix=/c/MinGW --enable-cxx CXXFLAGS=-g
$ make
$ make check
$ make install
$ make clean

설치가 성공적으로 끝나면 헤더 파일은 /c/MinGW/include 폴더에  라이브러리 파일은 /c/MinGW/lib 폴더에 생성된다.

 

단계 3.  MPIR 2.6.0 설치 후 테스트

아래세 제시된 C 소스와 C++ 소스를 각각 컴파일하여 실행해본다. (컴파일 명령은 각 소스의 주석문 참조)

 

 

4. mpir 설치 후 테스트를 위한 C 소스와 C++ 소스

 

 //  Filename: testMPIR_01.c
//
//      This has been tested with MPIR 2.5.2.
//
//   Compile: gcc -o testMPIR_01 testMPIR_01.c -lmpir
//   Execute: ./testMPIR_01
//
//    Or
//
//   Compile: cl testMPIR_01.c -I. mpir.lib
//   Execute: testMPIR_01
//
//   Date: 2013. 1. 16.
//   Copyright (c) PH Kim  ( pkim __AT__ scripts.pe.kr )

#include <stdio.h>
#include <mpir.h>

void foo (mpz_t result, const mpz_t param, int n)
{
    int i;

    mpz_mul_ui (result, param, n);
    gmp_printf ("Initialized r = %Zd\n", result);

    for (i = 1; i < n; i++) {
        mpz_add_ui (result, result, i*7);
        gmp_printf ("    r = %Zd  <--  r is added by %2d*7 = %3d\n", result, i, i*7);
    }
}


int main (void)
{
    mpz_t r, n;

    mpz_init (r);
    mpz_init_set_str (n, "123456", 0);

    mpz_set_si (r, 0);

    gmp_printf ("r = %Zd, n = %Zd\n", r, n);
    foo (r, n, 20L);
    gmp_printf ("Result is r = %Zd\n", r);

    mpz_clear(n);
    mpz_clear(r);

    return 0;
}

/*
Output:
r = 0, n = 123456
Initialized r = 2469120
    r = 2469127  <--  r is added by  1*7 =   7
    r = 2469141  <--  r is added by  2*7 =  14
    r = 2469162  <--  r is added by  3*7 =  21
    r = 2469190  <--  r is added by  4*7 =  28
    r = 2469225  <--  r is added by  5*7 =  35
    r = 2469267  <--  r is added by  6*7 =  42
    r = 2469316  <--  r is added by  7*7 =  49
    r = 2469372  <--  r is added by  8*7 =  56
    r = 2469435  <--  r is added by  9*7 =  63
    r = 2469505  <--  r is added by 10*7 =  70
    r = 2469582  <--  r is added by 11*7 =  77
    r = 2469666  <--  r is added by 12*7 =  84
    r = 2469757  <--  r is added by 13*7 =  91
    r = 2469855  <--  r is added by 14*7 =  98
    r = 2469960  <--  r is added by 15*7 = 105
    r = 2470072  <--  r is added by 16*7 = 112
    r = 2470191  <--  r is added by 17*7 = 119
    r = 2470317  <--  r is added by 18*7 = 126
    r = 2470450  <--  r is added by 19*7 = 133
Result is r = 2470450
*/

 

 

// Filename: testMPIR_02.cpp
//
//      This has been tested with MPIR 2.5.2.
//
//   Compile: g++ -o testMPIR_02 testMPIR_02.cpp -lmpirxx -lmpir
//   Execute: ./testMPIR_02
//
//    Or
//
//   Compile: cl /EHsc testMPIR_02.cpp -I. mpir.lib mpirxx.lib
//   Execute: testMPIR_02
//
//   Date: 2013. 1. 16.
//   Copyright (c) PH Kim ( pkim __AT__ scripts.pe.kr )

// #include <stdio.h>
#include <iostream>
#include <mpirxx.h>
#include <mpir.h>

using namespace std;

int main (void)
{
    mpz_class a, b, c;

    a = 1234;
    b = "-5678";
    c = a + b;

    cout << "Given two numbers are " << a << " and " << b << "." << endl;
    cout << "  Their sum is " << c << "." << endl;
    cout << "  Its absolute value is |" << a <<  " + (" << b << ")| = " << abs(c) << "." << endl;
    cout << "  Their product is " << a << "*(" << b << ") = " << (a*b) << "." << endl;

    return 0;
}

/*
Output:
Given two numbers are 1234 and -5678.
  Their sum is -4444.
  Its absolute value is |1234 + (-5678)| = 4444.
  Their product is 1234*(-5678) = -7006652.
*/

 

 

Posted by Scripter
,