🔀

C言語、C++、Rustで関数を使ってビット操作をする

に公開

はじめに

C23以降のC言語、C++20以降のC++、Rustは関数(メソッド)を使ってビット操作をすることができます。
これらの関数はC言語では<stdbit.h>、C++では<bit>、Rustではプリミティブ整数型のメソッドとして定義されています。
この記事では、これらの関数を操作ごとに紹介します。

整数値が2の累乗かを判定する

C言語ではstdc_has_single_bit関数を使って求めることができます。

#include <assert.h>
#include <stdbit.h>

assert(stdc_has_single_bit(0b10000u));

C++ではstd::has_single_bit関数を使って求めることができます。

#include <bit>
#include <cassert>

assert(std::has_single_bit(0b10000u));

Rustではis_power_of_twoメソッドを使って求めることができます。

assert!(0b10000_u32.is_power_of_two());

整数値を2の累乗値に切り上げる

C言語ではstdc_bit_ceil関数を使って求めることができます。

#include <assert.h>
#include <stdbit.h>

assert(stdc_bit_ceil(3u) == 4);

C++ではstd::bit_ceil関数を使って求めることができます。

#include <bit>
#include <cassert>

assert(std::bit_ceil(3u) == 4);

Rustではnext_power_of_twoメソッドを使って求めることができます。

assert_eq!(3_u32.next_power_of_two(), 4);

整数値を2の累乗値に切り下げる

C言語ではstdc_bit_floor関数を使って求めることができます。

#include <assert.h>
#include <stdbit.h>

assert(stdc_bit_floor(0b0110'0100u) == 0b0100'0000);

C++ではstd::bit_floor関数を使って求めることができます。

#include <bit>
#include <cassert>

assert(std::bit_floor(0b0110'0100u) == 0b0100'0000);

Rustではisolate_most_significant_oneメソッドを使って求めることができます。
現時点ではこのメソッドはnightlyチャンネルでのみ利用できます。

#![feature(isolate_most_least_significant_one)]

assert_eq!(0b0110_0100_u32.isolate_most_significant_one(), 0b0100_0000);

整数値を表現するのに必要な最小ビット数を求める

C言語ではstdc_bit_width関数を使って求めることができます。

#include <assert.h>
#include <stdbit.h>

assert(stdc_bit_width(0b1110u) == 4);

C++ではstd::bit_width関数を使って求めることができます。

#include <bit>
#include <cassert>

assert(std::bit_width(0b1110u) == 4);

Rustではbit_widthメソッドを使って求めることができます。
現時点ではこのメソッドはnightlyチャンネルでのみ利用できます。

#![feature(uint_bit_width)]

assert_eq!(0b1110_u32.bit_width(), 4);

最上位ビットから連続する0のビットを数える

C言語ではstdc_leading_zeros関数を使って求めることができます。

#include <assert.h>
#include <stdbit.h>
#include <stdint.h>

assert(stdc_leading_zeros(UINT32_MAX >> 2) == 2);

C++ではstd::countl_zero関数を使って求めることができます。

#include <bit>
#include <cassert>
#include <cstdint>

assert(std::countl_zero(UINT32_MAX >> 2) == 2);

Rustではleading_zerosメソッドを使って求めることができます。

assert_eq!((u32::MAX >> 2).leading_zeros(), 2);

最下位ビットから連続する0のビットを数える

C言語ではstdc_trailing_zeros関数を使って求めることができます。

#include <assert.h>
#include <stdbit.h>

assert(stdc_trailing_zeros(0b010'1000u) == 3);

C++ではstd::countr_zero関数を使って求めることができます。

#include <bit>
#include <cassert>

assert(std::countr_zero(0b010'1000u) == 3);

Rustではtrailing_zerosメソッドを使って求めることができます。

assert_eq!(0b010_1000_u32.trailing_zeros(), 3);

最上位ビットから連続する1のビットを数える

C言語ではstdc_leading_ones関数を使って求めることができます。

#include <assert.h>
#include <stdbit.h>
#include <stdint.h>

assert(stdc_leading_ones(~(UINT32_MAX>>2)) == 2);

C++ではstd::countl_one関数を使って求めることができます。

#include <bit>
#include <cassert>
#include <cstdint>

assert(std::countl_one(~(UINT32_MAX >> 2)) == 2);

Rustではleading_onesメソッドを使って求めることができます。

assert_eq!((!(u32::MAX >> 2)).leading_ones(), 2);

最下位ビットから連続する1のビットを数える

C言語ではstdc_trailing_ones関数を使って求めることができます。

#include <assert.h>
#include <stdbit.h>

assert(stdc_trailing_ones(0b101'0111u) == 3);

C++ではstd::countr_one関数を使って求めることができます。

#include <bit>
#include <cassert>

assert(std::countr_one(0b101'0111u) == 3);

Rustではtrailing_onesメソッドを使って求めることができます。

assert_eq!(0b101_0111_u32.trailing_ones(), 3);

1に設定されたビットを数える

C言語ではstdc_count_ones関数を使って求めることができます。

#include <assert.h>
#include <stdbit.h>

assert(stdc_count_ones(0b0100'1100u) == 3);

C++ではstd::popcount関数を使って求めることができます。

#include <bit>
#include <cassert>

assert(std::popcount(0b0100'1100u) == 3);

Rustではcount_onesメソッドを使って求めることができます。

assert_eq!(0b0100_1100_u32.count_ones(), 3);

まとめ

C言語 C++ Rust
整数値が2の累乗かを判定する stdc_has_single_bit std::has_single_bit is_power_of_two
整数値を2の累乗値に切り上げる stdc_bit_ceil std::bit_ceil next_power_of_two
整数値を2の累乗値に切り下げる stdc_bit_floor std::bit_floor isolate_most_significant_one
整数値を表現するのに必要な最小ビット数を求める stdc_bit_width std::bit_width bit_width
最上位ビットから連続する0のビットを数える stdc_leading_zeros std::countl_zero leading_zeros
最下位ビットから連続する0のビットを数える stdc_trailing_zeros std::countr_zero trailing_zeros
最上位ビットから連続する1のビットを数える stdc_leading_ones std::countl_one leading_ones
最下位ビットから連続する1のビットを数える stdc_trailing_ones std::countr_one trailing_ones
1に設定されたビットを数える stdc_count_ones std::popcount count_ones
GitHubで編集を提案

Discussion