2023年8月24日更新
新しいバージョン 6.3.0 がリリースされました。その内容に合わせて、記事を更新しました。
C言語やC++で多倍長演算を行うことができる GMP(GNU Multi-Precision)ライブラリのインストール手順を紹介します。
Windows で動作している cygwin 向けの解説です。Linux であれば、agt-get や yum などのパッケージマネージャを使うことが多いと思いますが、ソースコードからビルドする場合は、同じ手順になります。
GMP とは
このブログでは、C または C++ で多倍長の演算をするために The GNU Multiple Precision Arithmetic Library(GMP) を使います。このライブラリにより、メモリが許す限り、いくらでも大きい整数を使うことができます。整数だけではなく、有理数、浮動小数点数も任意精度で演算できるようになります。
ライセンスは、What is GMP のページから確認できます。Version 6 以降は、GNU LGPL v3 と GNU GPL v2 に従います。
基本的なインストール手順
Unix ベースのソースコードが公開されているソフトウェアをソースコードからビルドする場合の基本的な手順はだいたい同じです。なお、gcc などの開発ツールがすでにインストールされていることが前提となります。
- ソースコードアーカイブファイル(多くは tar ファイル)を入手して、展開する。
- ビルドする。多くの場合、以下の順番でコマンドを実行するだけです。
- ./configure
- make all
- make install
- インストールしたものを楽しむ。
アーカイブをダウンロードして展開する。
アーカイブを入手する
GMPのサイトにアクセスします。ソースコードのアーカイブファイルは、開発者のサイトから入手するようにしましょう。セキュリティ上のリスクが減ります。
記事執筆時点で、GMP の最新版かつ安定版は、2023年7月30日にリリースされた 6.3.0 です。リリースノートはこちらです。このときに先行開発版やベータ版を入手してもよいですが、安定して使いたい場合は、安定版(stable)をダウンロードしましょう。
GMP トップページの以下をクリックすると、アーカイブファイルがダウンロードできます。
ファイル名は、gmp-6.3.0.tar.xz です。このファイルは xz で圧縮されています。GNU tar 1.22 から xz フォーマットをサポートしています。オプション J を使用して解凍ができます。
前のバージョンである 6.2.1 と同じ lzip で圧縮されているアーカイブファイルは、ここからダウンロードできます。lzip のインストールは以下を参考にしてください。
lzip インストール(lz ファイルを使う場合)
インストールは、典型的な手順に従います。
lzip の公式サイトからダウンロードページに移ります。lzip-1.15.tar.gz をダウンロードします。ソースコードを展開したいフォルダにアーカイブファイルを格納して、以下のコマンドで、アーカイブを展開して、フォルダを移動します。$ は、シェルのプロンプトを表します。
$ tar -xvf lzip-1.15.tar.gz
$ cd lzip-1.15
基本的なインストール手順で紹介した以下のコマンドを順次実行します。
$ ./cofigure
$ make all
$ make install
GMP アーカイブの展開
これで、GMP のアーカイブファイルを展開する準備ができました。アーカイブファイル(gmp-6.3.0.tar.xz)をソースコードを展開したいフォルダに格納して、以下のコマンドを実行します。
$ tar Jxfv gmp-6.3.0.tar.xz
$ cd gmp-6.3.0/
ビルド
GMP をビルドしてインストールします。典型的な手順に加えて、GMP が正しく動作するか確認してみましょう(make check)。以下のコマンドを実行します。それぞれのコマンドは時間がかかる場合があります。
$ ./configure
$ make all
$ make check
$ make install
GMP を使う
多倍長整数の演算で使う人向けのC言語の見本ソースコードを提示しておきます。コンパイル(リンク)するときは、-lgmp オプションを付けてください。
/*
* Example for GNU Multiple Precision Arithmetic Library
*
* gcc example_gmp.c -lgmp
*/
#include <gmp.h>
int main(void)
{
mpz_t a; /* big integer a */
mpz_t b; /* big integer b */
mpz_t c; /* big integer c */
mpz_init(a); /* initialize a(= 0) */
mpz_init(b); /* initialize b(= 0) */
mpz_init_set_str (c, "123456789012345678901234567890", 10); /* set c */
mpz_set_si(a, 100); /* a = 100 */
gmp_scanf("%Zd", b); /* read b from stdin */
mpz_add(a, a, b); /* a = a + b */
mpz_add(b, c, c); /* b = c + c */
mpz_sub(c, b, a); /* c = b - a */
mpz_mul(b, a, c); /* b = a * c */
mpz_mul_si(a, a, 10); /* a = a * 10 */
mpz_fdiv_q(c, b, a); /* c = b / a */
gmp_printf("a = %Zd\n", a); /* print a */
gmp_printf("b = %Zd\n", b); /* print b */
gmp_printf("c = %Zd\n", c); /* print c */
mpz_clear(a); /* free a */
mpz_clear(b); /* free b */
mpz_clear(c); /* free c */
return 0;
}
実際の活用事例は、Project Euler 問題13の解答例などをご覧ください。
最後に
GMP(GNU Multi-Precision)ライブラリのインストール手順を紹介しました。ソースコードからビルドする場合にも同じような手順が適用できるため参考にしてください。