読者です 読者をやめる 読者になる 読者になる

kira924ageの雑記帳

日々の記録。

GMP-使い方メモ

C言語

はじめに

 今回は任意精度演算ライブラリ、The GNU Multiple Precision Arithmetic Library(GMP)の使い方についてメモ書きみたいなことをします。

[追記]任意精度演算がしたいなら普通にPythonとか使ったほうが良さそう。

用語

  • 任意精度演算・・・数値の桁の精度がメモリ容量以外に制限されない計算方法。ようするに大きい数が扱える。

環境構築

 本来はLinux向けのツールだがCygwinにインストールして使った。
インストール方法は以下のサイトを参考にした。
GMP の使い方

使い方

基本

 まずは、

#include "gmp.h"

でgmpをインクルードする。
GMPは、数値を格納する変数型として

がある。
宣言は、

mpz_t a, b, c;

のように行う。
変数は初期化をしないと使えないので

mpz_init(a);
mpz_init(b);
mpz_init(c);

のようにして初期化を行う。初期化をすると値は0になる。

mpz_set_str(a, "10000000000", 10);

のようにすると指定した基数で数列を代入してくれる。最後の10は基数。
他にも代入方法はあるけど、個人的によく使うのはこれ。
出力は以下のようにする。

mpz_out_str(stdout, 10, a);

使い終わった変数は

mpz_clear(a);

で領域を解放する。

四則演算

mpz_add(a, b, c);       /*a = b + c;*/
mpz_sub(a, b ,c);       /*a = b - c;*/
mpz_mul(a, b, c);       /*a = b * c;*/
mpz_cdiv_q(a, b ,c);    /*a = b / c;*/

その他の演算

mpz_sqrt(a, b);     /*aにbの平方の整数部を代入する*/
mpz_cmp(a, b)       /*aとbを比較し a > b なら正 a = b なら0 a < b なら負を返す*/
mpz_mod(a, b ,c);   /*a = b mod c*/
mpz_powm(result, a, b, c); /*result = (a^b) mod c*/
mpz_lcm(a, b, c)    /*aにbとcの最小公倍数を代入*/
mpz_gcd(a, b, c)    /*aにbとcの最大公約数を代入*/

サンプルコード

#include <stdio.h>
#include "gmp.h"
#define BASE 10
int main()
{
    mpz_t a,b,c,result; /*宣言*/
	
    mpz_init(a);   /*初期化*/
    mpz_init(b);
    mpz_init(c);
    mpz_init(result);
	
    mpz_set_str(a, "100", BASE);  /*代入*/
    mpz_set_str(b, "50", BASE);
    mpz_set_str(c, "3", BASE);
	
    mpz_add(result, a, b);   /*result = a + b*/	
    mpz_out_str (stdout, BASE, result);
    printf("\n");
	
    mpz_init(result);

    mpz_sub(result, a, b);   /*restlt = a - b*/
    mpz_out_str(stdout, BASE, result);
    printf("\n");
	
    mpz_init(result);
	
    mpz_mul(result, a, b);    /*result = a * b*/
    mpz_out_str(stdout, BASE, result);
    printf("\n");
	
    mpz_init(result);
	
    mpz_cdiv_q(result, a, b);  /*result = a / b*/
    mpz_out_str(stdout, BASE, result);
    printf("\n");
	
    mpz_init(result);
	
    mpz_sqrt(result, a);  /*resultにaの平方の整数部を代入*/
    mpz_out_str(stdout, BASE, result);
    printf("\n");
	
    mpz_init(result);
	
    mpz_mod(result, a, b); /*result = a mod b*/
    mpz_out_str(stdout, BASE, result);
    printf("\n");
	
    mpz_init(result);
	
    mpz_powm(result, c, a, b); /*result = (c^a) mod b*/
    mpz_out_str(stdout, BASE, result);
    printf("\n");
	
    mpz_clear(a);    /*領域の解放*/
    mpz_clear(b);
    mpz_clear(c);
    mpz_clear(result);

    return 0;
}

実行結果

150
50
5000
2
10
0
1

コンパイルは注意が必要で、Cygwinhoge.cというソースファイルをコンパイルしたい場合は、

gcc -I/usr/local/include -L/usr/local/lib -Wall -O3 -o hoge.exe hoge.c -lgmp

のようにする。

終わりに

 GMPでmpz_t型(整数型)を扱うのにはある程度慣れてきたが、mpf_t型(浮動小数点型)はまだまだ満足に扱えてないのでこれから何とかしたい。そのためには英語のドキュメントを読めるようにならないとだめだよなと思った(小並感)。