# ===== CodeLab: c-bitwise =====
# 以下代码片段按文章出现顺序拼接, 共 7 段

# ----- 片段 1 (c) -----
#include <stdio.h>

void print_bin(unsigned int x) {
    for (int i = 31; i >= 0; i--) {
        putchar(((x >> i) & 1u) ? '1' : '0');
        if (i % 4 == 0) putchar(' ');
    }
    putchar('\n');
}

int main(void) {
    print_bin(0x0C);   /* 0000 0000 0000 0000 0000 0000 0000 1100 */
    print_bin(0xA5);   /* ... 1010 0101 */
    return 0;
}

# ----- 片段 2 (c) -----
#include <stdio.h>

int main(void) {
    unsigned int a = 0x0C;   /* 二进制:1100 */
    unsigned int b = 0x0A;   /* 二进制:1010 */
    printf("a & b = 0x%X\n", a & b);   /* 1000 = 0x8 */
    printf("a | b = 0x%X\n", a | b);   /* 1110 = 0xE */
    printf("a ^ b = 0x%X\n", a ^ b);   /* 0110 = 0x6 */
    printf("~a    = 0x%X\n", ~a);
    return 0;
}

# ----- 片段 3 (c) -----
#include <stdio.h>

int main(void) {
    int n = 3;
    printf("%d << 1 = %d\n", n, n << 1);    /* 3 * 2  = 6  */
    printf("%d << 3 = %d\n", n, n << 3);    /* 3 * 8  = 24 */
    printf("%d >> 1 = %d\n", n, n >> 1);    /* 3 / 2  = 1  */

    int neg = -16;
    printf("%d >> 2 = %d\n", neg, neg >> 2); /* -16 / 4 = -4 */

    unsigned int mask = 1u << 7;   /* 第 7 位为 1,其余为 0 */
    printf("mask = 0x%X\n", mask); /* 0x80 */
    return 0;
}

# ----- 片段 4 (c) -----
#include <stdio.h>

int main(void) {
    int x = 42;
    printf("%d 是%s\n", x, (x & 1) ? "奇数" : "偶数");

    int a = 5, b = 9;
    a ^= b;
    b ^= a;
    a ^= b;                     /* 三步异或,不用临时变量 */
    printf("交换后:a=%d b=%d\n", a, b);

    int y = 64;
    printf("%d %s 2 的幂\n", y,
           (y > 0 && (y & (y - 1)) == 0) ? "是" : "不是");

    int p = -3, q = 8;
    printf("%s\n", ((p ^ q) < 0) ? "异号" : "同号");
    return 0;
}

# ----- 片段 5 (c) -----
#include <stdio.h>

#define PERM_READ  (1u << 0)   /* 0001 */
#define PERM_WRITE (1u << 1)   /* 0010 */
#define PERM_EXEC  (1u << 2)   /* 0100 */

int main(void) {
    unsigned int perm = 0;
    perm |= PERM_READ | PERM_WRITE;    /* 打开"读"和"写" */
    if (perm & PERM_READ) {
        printf("可以读\n");
    }
    if (perm & PERM_EXEC) {
        printf("可以执行\n");
    }
    perm &= ~PERM_WRITE;               /* 关掉"写" */
    printf("perm = 0x%X\n", perm);     /* 只剩读:0x1 */
    return 0;
}

# ----- 片段 6 (c) -----
#include <stdio.h>

int get_bit(unsigned int x, int pos) {
    return (x >> pos) & 1u;
}

unsigned int set_bit(unsigned int x, int pos) {
    return x | (1u << pos);
}

unsigned int clear_bit(unsigned int x, int pos) {
    return x & ~(1u << pos);
}

unsigned int toggle_bit(unsigned int x, int pos) {
    return x ^ (1u << pos);
}

int count_ones(unsigned int x) {
    int c = 0;
    while (x) {
        x &= x - 1;   /* 每次消掉最低位的 1 */
        c++;
    }
    return c;
}

int main(void) {
    unsigned int x = 0x0F;   /* 0000 1111 */
    printf("bit2 = %d\n", get_bit(x, 2));
    printf("set bit5  = 0x%X\n", set_bit(x, 5));
    printf("clear bit0 = 0x%X\n", clear_bit(x, 0));
    printf("1 的个数 = %d\n", count_ones(0x0F));
    return 0;
}

# ----- 片段 7 (c) -----
#include <stdio.h>

int main(void) {
    unsigned int color = 0x2E86AB;   /* 一种蓝色 */
    unsigned int r = (color >> 16) & 0xFF;
    unsigned int g = (color >> 8) & 0xFF;
    unsigned int b = color & 0xFF;
    printf("R=%u G=%u B=%u\n", r, g, b);   /* R=46 G=134 B=171 */

    unsigned int back = (r << 16) | (g << 8) | b;  /* 反向拼回 */
    printf("0x%X\n", back);
    return 0;
}
