知っているとコード量に差が出る!! bit系の便利な知識

競プロ

最初に

この記事は自分が知らなかったこと、もっと早く知っておきたかったと思うbit系の知識について書いた記事です。(bitとは何か?から全部説明しているような記事ではないです)

<bit> (C++20以上)

これらは全て符号なし整数型を引数にとる必要があるので注意!!

popcountを求める

uint32_t n = 5;

//pop_count
cout << popcount(n) << endl;//2

“引数以上の最小”の2の累乗値を返す

uint32_t n = 5;

//"引数以上の最小"の2の累乗値を返す
cout << bit_ceil(n) << endl;//8

“引数以下の最大”の2の累乗値を返す

uint32_t n = 5;

//"引数以下の最大"の2の累乗値を返す
cout << bit_floor(n) << endl;//4

連続した0や1の数を数える

uint32_t n = 5;

//[左 または 右]から、連続した[0 または 1]の数を返す
cout << countl_zero(n) << endl;//29
cout << countl_one(n) << endl;//0
cout << countr_zero(n) << endl;//0
cout << countr_one(n) << endl;//1

もっと詳しく知りたい場合はこちら

bit - cpprefjp C++日本語リファレンス
<bit>bit(C++20) <bit>ヘッダでは、ビット操作のための機能を定義する。 本ヘッダはフリースタンディング環境でも提供される。 変換 名前 説明 対応バージョン bit_cast ビットレベルの再解釈キャスト (functio...

整数を二進数で出力したい (C++20以上)

format()を使います

uint32_t n = 5;

//二進数としての出力
cout << format("{:0>表示する桁数b}", n) << endl;

format()自体のわかりやすい解説記事を見つけたので、リンクを貼っておきます↓

【C++】format() – C++でprintf()風の書式指定を使う | いざどりのtrial and error
はじめに C++で値を出力するにはストリームを使いますが、桁数設定や小数点以下の精度表示をするためにわざわざsetw()やsetprecision()する必要があるなど、マニピュレ...

bitsetをbit列から整数に変換したい

bitsetをintやlong longなどの整数に変換したい時がたまにあります。
そういう場合は「to_ulong()」を使います
(to_ullong()もあるし、文字列ならto_string()もある)

bitset<10> bitset_1(5);
    cout << bitset_1 << endl; //0000000101 そのまま出力ではビット列となる

    //int tmp_int = (int)bitset_1; <-みたいなことができると嬉しいのだができない

    int tmp_int = bitset_1.to_ulong();//5 to_ulong()なら整数に変換できる
    cout << tmp_int;

私はこれを最近まで知らなくってずっと

ビット列を全部見る。
立っていれば2kを加算。(k = 位置)
見終わったときの値が「整数に変換後の値」

としていて、大変コーディングが面倒でした…

整数同士のANDとかORとか…を求める方法

実は演算子があるらしい…↓

演算子役割
&AND
|OR
^XOR
~NOT
    int a = 5;
    int b = 3;

    //AND
    bitset<10> bitset_1(a & b);
    cout << bitset_1 << endl;//0000000001
    cout << (a & b) << endl;//1

    //OR
    bitset<10> bitset_2(a | b);
    cout << bitset_2 << endl;//0000000111
    cout << (a | b) << endl;//7

    //XOR
    bitset<10> bitset_3(a ^ b);
    cout << bitset_3 << endl;//0000000110
    cout << (a ^ b) << endl;//6

    //NOT
    bitset<10> bitset_4(~a);
    cout << bitset_4 << endl;//1111111010
    cout << (~a) << endl;//-6


これまた私は、この演算子を最近まで知らなくってですね…
今までは一度整数をビット列にしてから、forでビット列を全部見て行って…(以下略

この演算子も知っておくとコーディング速度に大きく差が出そうです

最後に

今回は、自分がもっと早く知りたかったbit系の知識について書きましたが「他にもこんな便利な事ができるよ」というものがあれば是非とも教えてくださいね♪
(もしあれば、筆者のX(Twitter)などに送っていただけると嬉しいです)

コメント

タイトルとURLをコピーしました