C++で使えるGCCコンパイラの組み込み関数(__builtin)の使い方まとめ
GCCコンパイラには、標準ライブラリとは別に便利な組み込み関数(ビルトイン関数)が多数用意されています。これらはコンパイラレベルで最適化されるため、非常に高速に動作し、特に競技プログラミングやビット演算処理で重宝します。
本記事では、代表的な組み込み関数である __builtin_popcount()、__builtin_parity()、__builtin_clz()、__builtin_ctz() の使い方をサンプルコード付きで解説します。
__builtin_popcount(x):1のビット数を数える
__builtin_popcount(x) は、整数型データの2進表現において、1になっているビットの個数を返す関数です。「母集団カウント(popcount)」とも呼ばれます。
サンプルコード
#include<iostream>
using namespace std;
int main() {
int n = 13; // 2進数では 1101
cout << n << " の2進表現に含まれる1の個数は " << __builtin_popcount(n);
return 0;
}実行結果
13 の2進表現に含まれる1の個数は 3
13 は2進数で 1101 となり、1が3つ含まれているため「3」が出力されます。
__builtin_parity(x):パリティ(偶奇性)を判定する
__builtin_parity(x) は、整数のパリティを判定する関数です。1のビット数が奇数であれば true(1) を、偶数であれば false(0) を返します。
サンプルコード
#include<iostream>
using namespace std;
int main() {
int n = 13; // 2進数では 1101
cout << n << " のパリティは " << __builtin_parity(n);
return 0;
}実行結果
13 のパリティは 1
13(1101)は1のビットが3つと奇数個あるため、結果は「1」となります。
__builtin_clz(x):先頭の連続する0を数える
__builtin_clz(x) は、整数の2進表現における先頭側(最上位ビット側)の連続した0の個数を返します。「clz」は Count Leading Zeros(先頭のゼロを数える)の略です。
サンプルコード
#include<iostream>
using namespace std;
int main() {
int n = 13; // 2進数では 1101
// 0000 0000 0000 0000 0000 0000 0000 1101(32ビット整数)
cout << n << " の先頭にある0の個数は " << __builtin_clz(n);
return 0;
}実行結果
13 の先頭にある0の個数は 28
32ビット整数の場合、全体は32桁なので、有効なビット4桁(1101)を除いた 32 − 4 = 28 個の先頭ゼロがカウントされます。
注意: 引数に 0 を渡した場合の動作は未定義です。実行前に必ず値が0でないことを確認してください。
__builtin_ctz(x):末尾の連続する0を数える
__builtin_ctz(x) は、整数の2進表現における末尾側(最下位ビット側)の連続した0の個数を返します。「ctz」は Count Trailing Zeros(末尾のゼロを数える)の略です。
サンプルコード
#include<iostream>
using namespace std;
int main() {
int n = 12; // 2進数では 1100
// 0000 0000 0000 0000 0000 0000 0000 1100(32ビット整数)
cout << n << " の末尾にある0の個数は " << __builtin_ctz(n);
return 0;
}実行結果
12 の末尾にある0の個数は 2
12(1100)は末尾に0が2つ続くため、結果は「2」となります。この値は「nを割り切れる2の最大乗」に相当するため、2の累乗計算にも応用できます。
補足:64ビット整数や他コンパイラへの対応
long型やlong long型に対しては、それぞれ__builtin_popcountl()/__builtin_popcountll()のように末尾にlやllを付けたバージョンを使用します。- これらの関数はGCC固有の拡張機能であり、C++の標準規格には含まれていません。MSVCなど別のコンパイラでは使えない場合があるため、移植性が必要なコードでは注意してください。
- C++20以降では、標準ライブラリの
<bit>ヘッダにあるstd::popcount()、std::countl_zero()、std::countr_zero()などを使うことで、同様の処理を移植性高く記述できます。
-
C++のswap()関数とは?2つの変数の値を入れ替える方法をサンプルコード付きで解説
swap()関数とは C++のswap()関数は、2つの値を入れ替える(交換する)ための関数です。この関数を利用すれば、一時的な第三の変数を自分で用意することなく、2つの変数の値を簡単に入れ替えることができます。 swap()関数の構文 void swap(int variable_name1, int variable_name2); 変数に値を代入してswap()関数に渡した場合、関数内では値の入れ替えが行われますが、呼び出し元の実際の変数の値は変わりません。これは、引数が「値渡し」で渡されるためです。実際の変数の値を入れ替えたい場合は、後述する「参照渡し」を使用します。 例1:s
-
LinuxにC++コンパイラをインストールする方法(GCC・Clangの手順を解説)
Linux上でC++プログラムをコンパイルするには、いくつかの選択肢があります。本記事では、代表的な2つのコンパイラ「GCC」と「Clang」の確認方法およびインストール手順について解説します。 GCCの確認とインストール ほとんどのLinuxディストリビューションには、標準でGCC(GNU Compiler Collection)がインストールされています。まずは、お使いのシステムにGCCが導入されているかどうかを確認しましょう。ターミナル(コマンドライン)から以下のコマンドを実行してください。 $ g++ -v GCCがすでにインストールされている場合は、次のようなバージョン情報が表示され