0Pricing
C Academy · レッスン

実践的なビット技巧

よく使うテクニックです。

「実践的なビット技巧」はCoddyKit上の無料C Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C Academyコースには全4レッスンが含まれています。

便利なビットテクニック

ビット演算子を理解すると、コンパクトなテクニックをいくつも使えるようになります。これらは高速で、実際のコードでも頻繁に登場します。

ここでは、最も一般的なものを見ていきましょう。

#include <stdio.h>

int main(void) {
    unsigned x = 6;
    printf("x & 1 = %u (odd if 1)\n", x & 1);
    return 0;
}

偶数か奇数か

最下位ビットで偶奇を判定できます。x & 1は奇数では1、偶数では0になります。

#include <stdio.h>

int main(void) {
    for (unsigned x = 0; x < 5; x++) {
        printf("%u is %s\n", x, (x & 1) ? "odd" : "even");
    }
    return 0;
}

2の累乗かどうかの確認

正の数は、セットされたビットがちょうど1つの場合に2の累乗です。x & (x - 1)は、その場合に限り0になります。

#include <stdio.h>

int is_pow2(unsigned x) {
    return x != 0 && (x & (x - 1)) == 0;
}

int main(void) {
    printf("%d %d %d\n", is_pow2(16), is_pow2(18), is_pow2(1));
    return 0;
}

最下位のセットビットをクリアする

x & (x - 1)は最下位のセットビットをクリアします。これは、セットビットを高速に数える処理の基礎です。

#include <stdio.h>

int main(void) {
    unsigned x = 0b10110;
    printf("before: %u\n", x);
    printf("after:  %u\n", x & (x - 1));
    return 0;
}

最下位のセットビットを分離する

x & (-x)は最下位のセットビットだけを残し、それ以外をオフにします。

これは2の補数表現に基づいています。

#include <stdio.h>

int main(void) {
    unsigned x = 0b10110;
    printf("lowest set bit = %u\n", x & (-x));
    return 0;
}

セットされたビットを数える

最下位のセットビットを繰り返しクリアすると、セットされたビットの数を数えられます。必要なステップ数は、セットされたビットの数と同じです。

#include <stdio.h>

int popcount(unsigned x) {
    int n = 0;
    while (x) { x &= (x - 1); n++; }
    return n;
}

int main(void) {
    printf("%d\n", popcount(255));
    printf("%d\n", popcount(0b1010));
    return 0;
}

一時変数なしで交換する

XOR交換を使うと、追加の記憶領域なしで2つの整数を交換できます。

#include <stdio.h>

int main(void) {
    int a = 3, b = 8;
    a ^= b; b ^= a; a ^= b;
    printf("a=%d b=%d\n", a, b);
    return 0;
}

2の累乗への切り上げ

最上位ビットを下位方向に広げてから1を加えることで、unsigned値を次の2の累乗へ切り上げられます。

#include <stdio.h>

unsigned next_pow2(unsigned v) {
    v--;
    v |= v >> 1; v |= v >> 2; v |= v >> 4;
    v |= v >> 8; v |= v >> 16;
    return v + 1;
}

int main(void) {
    printf("%u\n", next_pow2(17));
    printf("%u\n", next_pow2(100));
    return 0;
}

ビットが異なるか確認する

2つの値のビットが異なる位置では、a ^ bのビットがセットされます。これらを数えるとハミング距離が得られます。

#include <stdio.h>

int main(void) {
    unsigned a = 0b1101, b = 0b1011;
    unsigned diff = a ^ b;
    int count = 0;
    while (diff) { diff &= diff - 1; count++; }
    printf("hamming distance = %d\n", count);
    return 0;
}

分岐なしで絶対値を求める

符号ビットを使用すると、ifなしで絶対値を計算できます。負数の場合、マスクはすべて1になり、非負数の場合はすべて0になります。

#include <stdio.h>

int main(void) {
    int x = -42;
    int mask = x >> 31;
    int abs = (x + mask) ^ mask;
    printf("abs = %d\n", abs);
    return 0;
}

インデックスでビットをセットする

シフトとORを組み合わせると、実行時に計算した任意のビット位置をセットできます。

#include <stdio.h>

int main(void) {
    unsigned v = 0;
    int positions[] = {1, 3, 5};
    for (int i = 0; i < 3; i++) {
        v |= (1u << positions[i]);
    }
    printf("v = %u\n", v);
    return 0;
}

理解度チェック

ビットテクニックについての知識を確認しましょう。

まとめ

実用的なビットテクニックを学びました。

  • x & 1で偶数か奇数かを判定します。
  • x & (x - 1)で最下位のセットビットをクリアし、2の累乗かどうかを判定します。
  • x & (-x)で最下位のセットビットを分離します。
  • ポップカウント、XOR交換、ハミング距離、分岐なしの絶対値計算について学びました。

よくある質問

「実践的なビット技巧」レッスンは無料ですか?

はい。「実践的なビット技巧」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C Academyコースには全4レッスンが含まれています。

「実践的なビット技巧」で何を学びますか?

よく使うテクニックです。 ブラウザで直接実行するハンズオンコードでC Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「実践的なビット技巧」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC Academyレッスンでコードを書いて実行できますか?

はい。すべてのC Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ビット演算子
  2. シフト
  3. ビットマスクとフラグ
  4. 実践的なビット技巧
← C Academyに戻る