【Visual Studio 2017】MPIR(GMP)導入方法【多倍長整数ライブラリ】


はじめに

今回はVisual Studio 2017でMPIR(GMP)の導入方法について解説していきます。

そろそろMPIR(GMP)に手を出してみようかな
と思っている方や、
Visual StudioでプログラミングしてるけどMPIR(GMP)の入れ方がわからない
という方に向けて書いてます。

これを見れば誰でもMPIR(GMP)が導入できる!はず

ダウンロード

⇒こちらからMPIR〇〇source.zip をダウンロードします。


MPIR〇〇source.zip を選択します。

この解説では、 MPIR 3.0.0 source.zip を使います。

ダウンロード後

ダウンロードしたMPIR〇〇source.zipすべて展開(解凍) します。
今回、展開場所は Cドライブ直下(Windows (C:)) に置きます。

展開はそこそこ時間がかかります。

展開が終わったら次へ。

dll_mpir_gcをビルドする

展開したフォルダ、C:\mpir-〇〇を開くと
build.vcXX(XXは数字)というフォルダがあると思います。
1番数字が大きいものを開いてください。

mpir.slnファイルがあるのでVisual Studio 2017で起動します。

この解説ではC:\mpir-3.0.0\build.vc15\mpir.slnにありました。

起動したら最初に左上にある
DebugRelease
Win32x64に変えてください。

次にソリューションエクスプローラーから
dll_mpir_gcを選択し、右クリックすると出てくる
プロジェクトの再ターゲットを選択します。

OKを選択します。

次もソリューションエクスプローラーから
dll_mpir_gcを選択し、右クリックすると出てくる
ビルドを選択します。

無事に出力できました。

mpir.slnを閉じましょう。

Visual Studioでの設定

さて、ここからが本番です。
画面上のメニューの プロジェクト(P) から 〇〇のプロパティ を押します。

左の C/C++全般追加のインクルードディレクトリ に下記を追加します。
※ダウンロードしたMPIR(GMP)のバージョンによって適宜、名前を変えてください。

C:\mpir-3.0.0

左の リンカー全般追加のライブラリディレクトリ に下記のどちらかを追加します。
※ダウンロードしたMPIR(GMP)のバージョンによって適宜、名前を変えてください。

x86の場合
C:\mpir-3.0.0\build.vc15\dll_mpir_gc\Win32\Release
x64の場合
C:\mpir-3.0.0\build.vc15\dll_mpir_gc\x64\Release

左の リンカー入力追加の依存ファイル に下記を追加します。
※ダウンロードしたMPIR(GMP)のバージョンによって適宜、名前を変えてください。

mpir.lib

今回は、コンソールのプロジェクトとして使用するので、
左の リンカーシステムサブシステム

コンソール (/SUBSYSTEM:CONSOLE)

にしましょう。

最後に作成したプロジェクトの
ソースコードが入っているフォルダに
mpir.dllを入れたら準備完了です。

mpir.dllC:\mpir-〇〇\dll\(Win32 or x64)\Releaseにあります。

プロジェクト名を右クリックした後、
"エクスプローラーでフォルダを開く"
を押すと該当するフォルダが開きます。

この解説では、
C:\mpir-3.0.0\dll\x64\Release\mpir.dll
にありました。

MPIR(GMP)が使えるかどうかのテスト

今度はメルセンヌ素数を求めてみましょう。

Source.hpp
#include <cstdint>
#include <iostream>
#include <mpirxx.h>
#include <chrono>


bool lucasLehmerTest(const int_fast32_t p_) {
    mpz_class m = 1;
    m <<= p_;
    --m;
    mpz_class s = 4;
    for (int_fast32_t i = 2; i < p_; ++i)
        s = (s*s - 2) % m;
    if (s == 0) return true;
    return false;
}

bool lucasLehmerTestFast(const int_fast32_t p_) {
    mpz_class m{ 1 };
    m <<= p_;
    --m;

    mpz_class s{ 4 };
    mpz_class sqrt;
    for (int_fast32_t i{ 2 }; i < p_; ++i) {
        sqrt = s * s;
        s = (sqrt & m) + (sqrt >> p_);
        if (s >= m) s -= m;
        s -= 2;
    }
    if (s == 0) return true;
    return false;
}

int main() {

    std::chrono::system_clock::time_point  start, end;

    start = std::chrono::system_clock::now();

    if (lucasLehmerTestFast(9689)) std::cout << "TRUE" << std::endl;
    else std::cout << "FALSE" << std::endl;

    end = std::chrono::system_clock::now();
    std::cout << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << std::endl;

    return 0;
}
出力結果
TRUE
232

実行できました!

ソースコードのライセンス

These codes are licensed under CC0.

ソースコードは自由に使用してください。