yohhoyの日記

技術的メモをしていきたい日記

C++標準ライブラリのビット処理関数群

C++2a(C++20)標準ライブラリに追加される <bit> ヘッダについてメモ。

2020-05-11追記:(PDF)P1956R1が採択され*1、関数名が大幅に変更(ispow2has_single_bitceil2bit_ceilfloor2bit_floorlog2p1bit_width)された。"2の冪乗(powers of two)" への言及回避が目的とのこと...*2

// C++2a <bit>ヘッダ
namespace std {
  // sizeof(To) == sizeof(From)
  template<typename To, typename From>
    constexpr To bit_cast(const From& from) noexcept;

  // T = 符号なし整数型
  template <class T>
    constexpr bool has_single_bit(T x) noexcept;
  template <class T>
    constexpr T bit_ceil(T x);  // P1355R2変更
  template <class T>
    constexpr T bit_floor(T x) noexcept;
  template <class T>
    constexpr T bit_width(T x) noexcept;
}

2019-08-30追記:2019年7月会合で採択されたP1355R2によりceil2関数テンプレートからnoexcept指定が削除された。

関数 効果
bit_cast<To>(n) ビット表現を維持した型キャスト
(安全なreinterpret_cast)
has_single_bit(n) nが "2の冪乗" か否かを判定
bit_ceil(n) n以上で最小の "2の冪乗"
bit_floor(n) n以下で最大の "2の冪乗"
bit_width(n) 1 + floor(log2(n)) の整数演算*3
(ビット幅長)

入力値nと関数戻り値(n=0..16):

n has_single_bit bit_ceil bit_floor bit_width
0 false 1 0 0
1 true 1 1 1
2 true 2 2 2
3 false 4 2 2
4 true 4 4 3
5..7 false 8 4 3
8 true 8 8 4
9..15 false 16 8 4
16 true 16 16 5

関連URL

*1:https://github.com/cplusplus/draft/pull/3780

*2:P1956R1引用:"LEWG voted to rename some of the bit manipulation functions in order to avoid references to powers of two since manipulating bits should work in the future on bytes and machine words that are not numbers and for which numeric operations are not defined"

*3:初期提案P0556R0では “前提条件(Requires) n>0 あり log2(n) 関数” と定義されていたが、log2p1 に改名されC++標準ライブラリの広い契約(Wide Contracts)を満たす(→id:yohhoy:20180127)よう仕様変更された。