GMP(GNU Multi-Precision Library)の使い方2 四則演算編

GMPの基本的な使い方のうち今回は四則演算に関するAPIについてまとめます。

基本的にここにまとめるものは整数型mpz_tのものとします。
その他の型についてはGMPのサイトのマニュアルを確認してください。
たいていの場合、他の型でも同じように使えるはずです。

足し算

#include <stdio.h>
#include <gmp.h>

int main()
{
    mpz_t A, B, C;
    unsigned long ul = 12345;

    mpz_init_set_str(A, "123456789", 10); //初期化と代入を同時に行う
    mpz_init_set_str(B, "987654321", 10);
    mpz_init(C);

    mpz_add(C, A, B); //C = A + B (1111111110)
    mpz_out_str(stdout, 10, C);
    printf("\n");

    mpz_add_ui(C, C, ul); //C = C + ul (1111123455)
    //mpqにはない
    mpz_out_str(stdout, 10, C);
    printf("\n");

    return 0;
}

引き算

#include <stdio.h>
#include <gmp.h>

int main()
{
    mpz_t A, B, C;
    unsigned long ul = 12345678;

    mpz_init_set_str(A, "123456789", 10); //初期化と代入を同時に行う
    mpz_init_set_str(B, "987654321", 10);
    mpz_init(C);

    mpz_sub(C, A, B); //C = A - B (-864197532)
    mpz_out_str(stdout, 10, C);
    printf("\n");

    mpz_sub_ui(C, C, ul); //C = C - ul (-876543210)
    //mpqにはない
    mpz_out_str(stdout, 10, C);
    printf("\n");

    mpz_ui_sub(C, ul, C); //C = ul - C (888888888)
    //mpqにはない
    mpz_out_str(stdout, 10, C);
    printf("\n");

    return 0;
}

掛け算

#include <stdio.h>
#include <gmp.h>

int main()
{
    mpz_t A, B, C;
    unsigned long ul = 9;
    signed long sl = -1;

    mpz_init_set_str(A, "12345", 10); //初期化と代入を同時に行う
    mpz_init_set_str(B, "98765", 10);
    mpz_init(C);

    mpz_mul(C, A, B); //C = A * B (1219253925)
    mpz_out_str(stdout, 10, C);
    printf("\n");

    mpz_mul_ui(C, C, ul); //C = C * ul (10973285325)
    //mpqにはない
    mpz_out_str(stdout, 10, C);
    printf("\n");

    mpz_mul_si(C, ul, C); //C = C * sl (-10973285325)
    //mpf,mpqには無い
    mpz_out_str(stdout, 10, C);
    printf("\n");

    return 0;
}

割り算

整数型の割り算は結果の商の丸め方によって様々な関数が用意されています。

#include <stdio.h>
#include <gmp.h>

int main()
{
    mpz_t A, B, Q, R;
    unsigned long ul = 9;
    signed long sl = -1;

    mpz_init_set_str(A, "10", 10); //初期化と代入を同時に行う
    mpz_init_set_str(B, "3", 10);
    mpz_init(Q);
    mpz_init(R);

    //cdivのcはceil(天井)。天井関数。
    //商Qを+∞に向かって丸める。そのため剰余Rは割る数と逆の符号になる。
    //結果の商をQに代入
    mpz_cdiv_q(Q, A, B); //Q = 10 / 3 (3.33333なので4に)
    mpz_out_str(stdout, 10, R);
    printf("\n");

    //結果の剰余をRに代入
    mpz_cdiv_r(R, A, B); //Q * 3 + R = 10 (Qが4なのでRは-2に)
    mpz_out_str(stdout, 10, R);
    printf("\n");

    //結果の商をQ,剰余をRに代入
    mpz_cdiv_qr(Q, R, A, B);
    mpz_out_str(stdout, 10, C);
    printf("\n");

    //fdivのfはfloor(床)。床関数。
    //商を-∞に向かって丸める
    mpz_fdiv_q(Q, A, B);
    mpz_fdiv_r(R, A, B); 
    mpz_fdiv_qr(Q, R, A, B);

    //tdivのtはtruncate。小数部は切り捨てられる。
    mpz_tdiv_q(Q, A, B);
    mpz_tdiv_r(R, A, B);
    mpz_tdiv_qr(Q, R, A, B);

    //あまりを求める
    mpz_mod(R, A, B); //R = A % B

    return 0;
}

mpf_t型、mpq_f型の場合

#include <stdio.h>
#include <gmp.h>

int main()
{
    mpf_t A, B, F;
    mpq_t C, D, Q;

    mpf_init_set_str(A, "10", 10); //初期化と代入を同時に行う
    mpf_init_set_str(B, "3", 10);
    mpf_init(F);
    mpq_init(C);
    mpq_init(D);
    mpq_set_str(C, "1/3", 10);
    mpq_set_str(D, "1/5", 10);
    mpq_init(Q);


    mpf_div(F, A, B); //F = A / B (0.3333333333e1)
    mpf_out_str(stdout, 10, 10, F);
    printf("\n");

    mpq_div(Q, C, D); //Q = C / D (5/3)
    mpq_out_str(stdout, 10, Q);
    printf("\n");

    return 0;
}
カテゴリー: C, Ubuntu, ソフトウェア パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です