C#で特定のビットを変更する

C#で整数型の特定のビットを立てたり落としたりする方法です。制御系の処理だと結構やるのと思いますが、C#でこういった操作をする事は珍しいので紹介したいと思います。

特定のビット「だけ」を変更するのは、一般的な方法論があるのでそちらを先に紹介したいと思います。

0を1へ変更する場合

例えば0x5(0101)と、0xA(1010)それぞれの2ビット目を1にしたい場合、まず全部ゼロでフィールドを埋めて、変更したいビット(=2ビット目)だけ1にした種(マスク値)を用意します。

// マスク値
0010 (2)

で、それを変更したい整数(0x5{0101}、0xA{1010})とORを取ります。

0101 OR 0010 = 0111 // 0 → 1に変わる
1010 OR 0010 = 1010 // 1 → 1の時は変わらない

1を0へ変更する場合

0x5(0101)と、0xA(1010)それぞれの2ビット目を0にしたい場合、対象ビットの立ったマスク値を用意するところまでは同じですが、今度はそれを反転したものをマスク値とします。

00101101 // マスク値を反転する

で、それを変更したい整数(0x5{0101}、0xA{1010})とANDを取ります。

0101 AND 1101 = 0101 // 0 → 0の時は変わらない
1010 AND 1101 = 1000 // 0 → 1に変わる

C#で実装する

C#での実装ですが、0→1、1→0はif分岐するしかないのでそれぞれのケースを実装します。

以下のコードはsrcで指定した整数の第2引数ビットを第3引数で指定した値に変更します。

public static class BitUtility
{
    public static void ChangeBit(ref int src, int bit, bool val /* true = 1 / false = 0 */)
    {
        int mask = 1 << bit;
        src = val ? src | mask : src & ~mask;
    }
}

今回使用した記号はビット演算でC#では以下のように定義されています。

演算子 説明
| OR
& AND
~(チルダ) NOT(反転)