ビット演算

  1. このような短い関数では、マジック定数を使用しても問題はないだろう。そうしないと、コードが複雑になりすぎる可能性がある。
    string dotted(uint address) {
        return format("%s.%s.%s.%s",
                      (address >> 24) & 0xff,
                      (address >> 16) & 0xff,
                      (address >>  8) & 0xff,
                      (address >>  0) & 0xff);
    }
    D

    型は符号なし型であるため、左側から値に挿入されるビットはすべて値0になる。そのため、24ビットシフトされる値をマスクする必要はない。さらに、0ビットシフトは効果がないため、その操作も削除できる。

    string dotted(uint address) {
        return format("%s.%s.%s.%s",
                       address >> 24,
                      (address >> 16) & 0xff,
                      (address >>  8) & 0xff,
                       address        & 0xff);
    }
    D
  2. 各オクテットを IPv4 アドレスの適切な位置にシフトしてから、これらの式を"OR"で結合することができる。
    uint ipAddress(ubyte octet3,    // 最も重要なオクテット
                   ubyte octet2,
                   ubyte octet1,
                   ubyte octet0) {  // 最も重要度の低いオクテット
        return
            (octet3 << 24) |
            (octet2 << 16) |
            (octet1 <<  8) |
            (octet0 <<  0);
    }
    D
  3. 次の方法は、すべてのビットが1の値から始める。まず、値を右にシフトして上位ビットを0にしてから、左にシフトして下位ビットを0にする。
    uint mask(int lowestBit, int width) {
        uint result = uint.max;
        result >>= (uint.sizeof * 8) - width;
        result <<= lowestBit;
        return result;
    }
    D

    uint.maxは、すべてのビットが1の値である。あるいは、0の補数である値から計算を開始することもできる。これは、uint.maxと同じだ。

    uint result = ~0;
    // ...
    D