2022年8月26日に「GMP ライブラリをソースコードからインストールする」という記事を投稿しました。GMP のサイトを確認すると、新しい 6.3.0 がリリースされていました。ブログ記事は、6.3.0 向けに更新しました。
この機会に GMP について、追加の情報を紹介します。
GMP とは
The GNU Multiple Precision Arithmetic Library(GMP) は、(メモリが許す限り)任意長の多倍長整数を使うことができます。整数だけではなく、有理数、浮動小数点数も任意精度で演算することができます。
多倍量整数は、Boost ライブラリでも提供されていますが、わたしは昔から GMP を使っていました。
コード例(ABC275B ABC-DEF)
ABC275B(解説)では、剰余を計算しながら、最終的に a * b * c – d * e * f の値を求めます。
整数の桁に制限がない Python では、以下のようにすっきりと書けます。
a, b, c, d, e, f = map(int, input().split())
print(((a * b * c) - (d * e * f)) % 998244353)
C++ も GMP を使うと、以下のように Python に近いプログラムになります。
#include <bits/stdc++.h>
#include <gmpxx.h>
using namespace std;
int main()
{
mpz_class a, b, c, d, e, f;
cin >> a >> b >> c >> d >> e >> f;
cout << (a * b * c - d * e * f) % 998244353 << endl;
return 0;
}
ただし、このプログラムは、ABC275Bのジャッジ環境では動作しません。ABC314以降のコードテストの環境で試すことができます。
AtCoder 環境で使えるようになりました
前述のように AtCoder Beginner Contest(ABC)では、314回から、使用できる言語とバージョンが更新された新ジャッジで行われています。
使用できる言語、実装、コンパイラオプション、ライブラリについては、このページに一覧として掲載されています。
C言語については、GMP 対応されていません。C++については、以下の対応状況でした。
言語の表記 | 実装 | 言語バージョン | GMP対応 |
C++17 (gcc 12.2) | gcc | C++17 | × |
C++20 (gcc 12.2) | gcc | C++20 | ○ |
C++23 (gcc 12.2) | gcc | C++23 | ○ |
C++17 (Clang 16.0.5) | Clang | C++17 | × |
C++20 (Clang 16.0.5) | Clang | C++20 | × |
C++23 (Clang 16.0.5) | Clang | C++23 | × |
まとめると、gcc で C++20 以降を選択すれば、AtCoder でも GMP が使えます。GMP バージョンは、6.2.1 です。
- gcc の C++17 は、ライブラリとして一覧に掲載されていませんでした。
- Clang はすべての言語バージョンで、ライブラリには記述がありました。ただし、-lgmpxx -lgmp の指定が抜けているためか、リンクエラーがでていました(2023年8月24日時点)。
最後に
AtCoder では、使うプログラミング言語の有利不利を減らすために64ビット長を超える整数が必要な問題を避けているようです。
一方、日常のプログラミングでは、多倍長整数を使うことがあります。GMP ライブラリ 6.3.0 のリリースにより、知識を更新するよい機会になりました。