c

examples

examples.c🔧
/**
 * =============================================================================
 * Bit Manipulation in C - Comprehensive Examples
 * =============================================================================
 * 
 * This file demonstrates bit manipulation techniques in C.
 * 
 * Compile: gcc -Wall -Wextra -std=c99 -o examples examples.c
 * Run: ./examples
 * 
 * =============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <limits.h>

// =============================================================================
// Helper Functions for Output
// =============================================================================

/**
 * Print binary representation of an 8-bit value
 */
void print_binary8(uint8_t value, const char *label) {
    printf("%s: ", label);
    for (int i = 7; i >= 0; i--) {
        printf("%d", (value >> i) & 1);
        if (i == 4) printf(" ");  // Space between nibbles
    }
    printf(" (0x%02X, %u)\n", value, value);
}

/**
 * Print binary representation of a 32-bit value
 */
void print_binary32(uint32_t value, const char *label) {
    printf("%s: ", label);
    for (int i = 31; i >= 0; i--) {
        printf("%d", (value >> i) & 1);
        if (i % 8 == 0 && i > 0) printf(" ");
    }
    printf("\n");
    printf("       Hex: 0x%08X, Decimal: %u\n", value, value);
}

// =============================================================================
// Example 1: Basic Bitwise Operators
// =============================================================================

void example1_bitwise_operators(void) {
    printf("=== Example 1: Basic Bitwise Operators ===\n\n");
    
    uint8_t a = 0b10101100;  // 172
    uint8_t b = 0b11001010;  // 202
    
    print_binary8(a, "A      ");
    print_binary8(b, "B      ");
    printf("\n");
    
    // AND
    uint8_t and_result = a & b;
    print_binary8(and_result, "A & B  ");
    printf("         (bits set in BOTH A and B)\n\n");
    
    // OR
    uint8_t or_result = a | b;
    print_binary8(or_result, "A | B  ");
    printf("         (bits set in A OR B)\n\n");
    
    // XOR
    uint8_t xor_result = a ^ b;
    print_binary8(xor_result, "A ^ B  ");
    printf("         (bits that are DIFFERENT)\n\n");
    
    // NOT
    uint8_t not_a = ~a;
    print_binary8(not_a, "~A     ");
    printf("         (all bits INVERTED)\n\n");
    
    printf("\n");
}

// =============================================================================
// Example 2: Bit Shifting
// =============================================================================

void example2_bit_shifting(void) {
    printf("=== Example 2: Bit Shifting ===\n\n");
    
    uint8_t value = 0b00101100;  // 44
    
    print_binary8(value, "Original");
    printf("\n");
    
    // Left shifts
    printf("Left shifts (multiply by 2 each shift):\n");
    print_binary8(value << 1, "  << 1  ");
    print_binary8(value << 2, "  << 2  ");
    print_binary8(value << 3, "  << 3  ");
    printf("\n");
    
    // Right shifts
    printf("Right shifts (divide by 2 each shift):\n");
    print_binary8(value >> 1, "  >> 1  ");
    print_binary8(value >> 2, "  >> 2  ");
    print_binary8(value >> 3, "  >> 3  ");
    printf("\n");
    
    // Creating bit positions
    printf("Creating bit at position n with (1 << n):\n");
    for (int i = 0; i < 8; i++) {
        char label[20];
        sprintf(label, "  1 << %d", i);
        print_binary8(1 << i, label);
    }
    
    printf("\n");
}

// =============================================================================
// Example 3: Setting, Clearing, and Toggling Bits
// =============================================================================

void example3_bit_manipulation(void) {
    printf("=== Example 3: Setting, Clearing, and Toggling Bits ===\n\n");
    
    uint8_t value = 0b00000000;
    
    print_binary8(value, "Start  ");
    printf("\n");
    
    // Set bits 1, 3, 5, 7
    printf("Setting bits 1, 3, 5, 7:\n");
    value |= (1 << 1);  print_binary8(value, "  Set 1");
    value |= (1 << 3);  print_binary8(value, "  Set 3");
    value |= (1 << 5);  print_binary8(value, "  Set 5");
    value |= (1 << 7);  print_binary8(value, "  Set 7");
    printf("\n");
    
    // Clear bits 1, 5
    printf("Clearing bits 1, 5:\n");
    value &= ~(1 << 1);  print_binary8(value, "  Clr 1");
    value &= ~(1 << 5);  print_binary8(value, "  Clr 5");
    printf("\n");
    
    // Toggle bits 0, 3, 7
    printf("Toggling bits 0, 3, 7:\n");
    value ^= (1 << 0);  print_binary8(value, "  Tog 0");
    value ^= (1 << 3);  print_binary8(value, "  Tog 3");
    value ^= (1 << 7);  print_binary8(value, "  Tog 7");
    printf("\n");
    
    // Check specific bits
    printf("Checking bits:\n");
    for (int i = 0; i < 8; i++) {
        int is_set = (value >> i) & 1;
        printf("  Bit %d is %s\n", i, is_set ? "SET" : "CLEAR");
    }
    
    printf("\n");
}

// =============================================================================
// Example 4: Bit Masks
// =============================================================================

void example4_bit_masks(void) {
    printf("=== Example 4: Bit Masks ===\n\n");
    
    uint8_t value = 0xAB;  // 1010 1011
    
    print_binary8(value, "Value     ");
    printf("\n");
    
    // Extract nibbles using masks
    uint8_t low_mask = 0x0F;
    uint8_t high_mask = 0xF0;
    
    print_binary8(low_mask, "Low Mask  ");
    print_binary8(high_mask, "High Mask ");
    printf("\n");
    
    uint8_t low_nibble = value & low_mask;
    uint8_t high_nibble = (value & high_mask) >> 4;
    
    print_binary8(low_nibble, "Low Nibble ");
    print_binary8(high_nibble, "High Nibble");
    printf("\n");
    
    // Combine nibbles
    printf("Combining nibbles (swap them):\n");
    uint8_t swapped = (low_nibble << 4) | high_nibble;
    print_binary8(swapped, "Swapped   ");
    printf("\n");
    
    // Extract specific bit range (bits 2-5)
    printf("Extracting bits 2-5:\n");
    uint8_t range_mask = 0b00111100;  // Bits 2-5
    print_binary8(range_mask, "Range Mask");
    uint8_t extracted = (value & range_mask) >> 2;
    print_binary8(extracted, "Extracted ");
    
    printf("\n");
}

// =============================================================================
// Example 5: Flags and Flag Operations
// =============================================================================

// Define flags using bit positions
#define FLAG_READ      (1 << 0)   // 0x01
#define FLAG_WRITE     (1 << 1)   // 0x02
#define FLAG_EXECUTE   (1 << 2)   // 0x04
#define FLAG_DELETE    (1 << 3)   // 0x08
#define FLAG_HIDDEN    (1 << 4)   // 0x10
#define FLAG_SYSTEM    (1 << 5)   // 0x20
#define FLAG_READONLY  (1 << 6)   // 0x40
#define FLAG_ARCHIVE   (1 << 7)   // 0x80

void print_flags(uint8_t flags) {
    printf("Flags set: ");
    if (flags & FLAG_READ)     printf("READ ");
    if (flags & FLAG_WRITE)    printf("WRITE ");
    if (flags & FLAG_EXECUTE)  printf("EXEC ");
    if (flags & FLAG_DELETE)   printf("DEL ");
    if (flags & FLAG_HIDDEN)   printf("HIDE ");
    if (flags & FLAG_SYSTEM)   printf("SYS ");
    if (flags & FLAG_READONLY) printf("RO ");
    if (flags & FLAG_ARCHIVE)  printf("ARCH ");
    if (flags == 0)            printf("(none)");
    printf("\n");
}

void example5_flags(void) {
    printf("=== Example 5: Flags and Flag Operations ===\n\n");
    
    uint8_t file_permissions = 0;
    
    printf("Initial state:\n");
    print_binary8(file_permissions, "Permissions");
    print_flags(file_permissions);
    printf("\n");
    
    // Set read and write
    printf("Setting READ and WRITE:\n");
    file_permissions |= FLAG_READ | FLAG_WRITE;
    print_binary8(file_permissions, "Permissions");
    print_flags(file_permissions);
    printf("\n");
    
    // Add execute
    printf("Adding EXECUTE:\n");
    file_permissions |= FLAG_EXECUTE;
    print_binary8(file_permissions, "Permissions");
    print_flags(file_permissions);
    printf("\n");
    
    // Check if writable
    if (file_permissions & FLAG_WRITE) {
        printf("File is writable!\n\n");
    }
    
    // Remove write permission
    printf("Removing WRITE (making read-only):\n");
    file_permissions &= ~FLAG_WRITE;
    file_permissions |= FLAG_READONLY;
    print_binary8(file_permissions, "Permissions");
    print_flags(file_permissions);
    printf("\n");
    
    // Toggle hidden
    printf("Toggling HIDDEN:\n");
    file_permissions ^= FLAG_HIDDEN;
    print_binary8(file_permissions, "Permissions");
    print_flags(file_permissions);
    
    file_permissions ^= FLAG_HIDDEN;
    print_binary8(file_permissions, "Toggle again");
    print_flags(file_permissions);
    
    printf("\n");
}

// =============================================================================
// Example 6: Common Bit Manipulation Functions
// =============================================================================

/**
 * Count the number of set bits (population count)
 */
int count_set_bits(uint32_t n) {
    int count = 0;
    while (n) {
        n &= (n - 1);  // Clear lowest set bit
        count++;
    }
    return count;
}

/**
 * Check if n is a power of 2
 */
bool is_power_of_2(uint32_t n) {
    return n > 0 && (n & (n - 1)) == 0;
}

/**
 * Find position of lowest set bit (0-indexed, -1 if no bit set)
 */
int find_lowest_set_bit(uint32_t n) {
    if (n == 0) return -1;
    int pos = 0;
    while ((n & 1) == 0) {
        n >>= 1;
        pos++;
    }
    return pos;
}

/**
 * Find position of highest set bit (0-indexed, -1 if no bit set)
 */
int find_highest_set_bit(uint32_t n) {
    if (n == 0) return -1;
    int pos = 0;
    while (n >>= 1) {
        pos++;
    }
    return pos;
}

/**
 * Get next power of 2 >= n
 */
uint32_t next_power_of_2(uint32_t n) {
    if (n == 0) return 1;
    n--;
    n |= n >> 1;
    n |= n >> 2;
    n |= n >> 4;
    n |= n >> 8;
    n |= n >> 16;
    return n + 1;
}

/**
 * Reverse bits in a byte
 */
uint8_t reverse_byte(uint8_t b) {
    b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
    b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
    b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
    return b;
}

void example6_common_functions(void) {
    printf("=== Example 6: Common Bit Manipulation Functions ===\n\n");
    
    // Count set bits
    printf("Counting set bits:\n");
    uint32_t values[] = {0, 1, 7, 15, 16, 255, 0xFFFFFFFF};
    for (int i = 0; i < 7; i++) {
        printf("  count_set_bits(0x%X) = %d\n", 
               values[i], count_set_bits(values[i]));
    }
    printf("\n");
    
    // Power of 2 check
    printf("Power of 2 check:\n");
    uint32_t pow2_test[] = {0, 1, 2, 3, 4, 5, 8, 15, 16, 17, 32, 64, 100, 128};
    for (int i = 0; i < 14; i++) {
        printf("  is_power_of_2(%u) = %s\n", 
               pow2_test[i], is_power_of_2(pow2_test[i]) ? "true" : "false");
    }
    printf("\n");
    
    // Find lowest/highest set bit
    printf("Finding bit positions:\n");
    uint32_t bit_test[] = {0, 1, 8, 12, 128, 0x8000};
    for (int i = 0; i < 6; i++) {
        printf("  Value 0x%04X: lowest=%d, highest=%d\n",
               bit_test[i], 
               find_lowest_set_bit(bit_test[i]),
               find_highest_set_bit(bit_test[i]));
    }
    printf("\n");
    
    // Next power of 2
    printf("Next power of 2:\n");
    uint32_t next_test[] = {0, 1, 2, 3, 5, 7, 9, 15, 17, 100};
    for (int i = 0; i < 10; i++) {
        printf("  next_power_of_2(%u) = %u\n", 
               next_test[i], next_power_of_2(next_test[i]));
    }
    printf("\n");
    
    // Bit reversal
    printf("Bit reversal:\n");
    uint8_t rev_test[] = {0x01, 0x80, 0x0F, 0xF0, 0xAA, 0x55, 0x12};
    for (int i = 0; i < 7; i++) {
        uint8_t reversed = reverse_byte(rev_test[i]);
        printf("  0x%02X -> 0x%02X (", rev_test[i], reversed);
        for (int j = 7; j >= 0; j--) printf("%d", (rev_test[i] >> j) & 1);
        printf(" -> ");
        for (int j = 7; j >= 0; j--) printf("%d", (reversed >> j) & 1);
        printf(")\n");
    }
    
    printf("\n");
}

// =============================================================================
// Example 7: Bit Fields in Structures
// =============================================================================

// Network packet header using bit fields
struct PacketHeader {
    unsigned int version : 4;       // 4 bits for version
    unsigned int type : 4;          // 4 bits for type
    unsigned int priority : 3;      // 3 bits for priority (0-7)
    unsigned int flags : 5;         // 5 bits for flags
    unsigned int sequence : 16;     // 16 bits for sequence number
};

// Status register using bit fields
struct StatusRegister {
    unsigned int ready : 1;
    unsigned int busy : 1;
    unsigned int error : 1;
    unsigned int overflow : 1;
    unsigned int underflow : 1;
    unsigned int interrupt : 1;
    unsigned int reserved : 2;
};

void example7_bit_fields(void) {
    printf("=== Example 7: Bit Fields in Structures ===\n\n");
    
    // Packet header
    printf("Packet Header Example:\n");
    struct PacketHeader packet = {0};
    
    packet.version = 4;
    packet.type = 1;
    packet.priority = 5;
    packet.flags = 0x1F;
    packet.sequence = 12345;
    
    printf("  Version:  %u\n", packet.version);
    printf("  Type:     %u\n", packet.type);
    printf("  Priority: %u\n", packet.priority);
    printf("  Flags:    0x%02X\n", packet.flags);
    printf("  Sequence: %u\n", packet.sequence);
    printf("  Size:     %zu bytes\n", sizeof(packet));
    printf("\n");
    
    // Status register
    printf("Status Register Example:\n");
    struct StatusRegister status = {0};
    
    status.ready = 1;
    status.busy = 0;
    status.error = 0;
    status.overflow = 0;
    status.underflow = 0;
    status.interrupt = 1;
    
    printf("  Ready:     %s\n", status.ready ? "YES" : "NO");
    printf("  Busy:      %s\n", status.busy ? "YES" : "NO");
    printf("  Error:     %s\n", status.error ? "YES" : "NO");
    printf("  Overflow:  %s\n", status.overflow ? "YES" : "NO");
    printf("  Underflow: %s\n", status.underflow ? "YES" : "NO");
    printf("  Interrupt: %s\n", status.interrupt ? "YES" : "NO");
    printf("  Size:      %zu bytes\n", sizeof(status));
    
    printf("\n");
}

// =============================================================================
// Example 8: RGB Color Manipulation
// =============================================================================

typedef uint32_t Color;  // ARGB format: 0xAARRGGBB

// Macros for color manipulation
#define COLOR_ALPHA(c)  (((c) >> 24) & 0xFF)
#define COLOR_RED(c)    (((c) >> 16) & 0xFF)
#define COLOR_GREEN(c)  (((c) >> 8) & 0xFF)
#define COLOR_BLUE(c)   ((c) & 0xFF)

#define MAKE_COLOR(a, r, g, b) \
    ((((a) & 0xFF) << 24) | (((r) & 0xFF) << 16) | \
     (((g) & 0xFF) << 8) | ((b) & 0xFF))

void print_color(Color c, const char *name) {
    printf("%s: 0x%08X (A=%3u, R=%3u, G=%3u, B=%3u)\n",
           name, c,
           COLOR_ALPHA(c), COLOR_RED(c),
           COLOR_GREEN(c), COLOR_BLUE(c));
}

Color blend_colors(Color c1, Color c2) {
    uint8_t a = (COLOR_ALPHA(c1) + COLOR_ALPHA(c2)) / 2;
    uint8_t r = (COLOR_RED(c1) + COLOR_RED(c2)) / 2;
    uint8_t g = (COLOR_GREEN(c1) + COLOR_GREEN(c2)) / 2;
    uint8_t b = (COLOR_BLUE(c1) + COLOR_BLUE(c2)) / 2;
    return MAKE_COLOR(a, r, g, b);
}

Color invert_color(Color c) {
    return MAKE_COLOR(
        COLOR_ALPHA(c),
        255 - COLOR_RED(c),
        255 - COLOR_GREEN(c),
        255 - COLOR_BLUE(c)
    );
}

Color grayscale(Color c) {
    // Using luminosity formula
    uint8_t gray = (uint8_t)(
        0.299 * COLOR_RED(c) +
        0.587 * COLOR_GREEN(c) +
        0.114 * COLOR_BLUE(c)
    );
    return MAKE_COLOR(COLOR_ALPHA(c), gray, gray, gray);
}

void example8_color_manipulation(void) {
    printf("=== Example 8: RGB Color Manipulation ===\n\n");
    
    // Create some colors
    Color red    = MAKE_COLOR(255, 255, 0, 0);
    Color green  = MAKE_COLOR(255, 0, 255, 0);
    Color blue   = MAKE_COLOR(255, 0, 0, 255);
    Color white  = MAKE_COLOR(255, 255, 255, 255);
    Color yellow = MAKE_COLOR(255, 255, 255, 0);
    
    printf("Original colors:\n");
    print_color(red, "  Red   ");
    print_color(green, "  Green ");
    print_color(blue, "  Blue  ");
    print_color(white, "  White ");
    print_color(yellow, "  Yellow");
    printf("\n");
    
    // Blend colors
    printf("Blending colors:\n");
    print_color(blend_colors(red, blue), "  Red+Blue  ");
    print_color(blend_colors(red, green), "  Red+Green ");
    print_color(blend_colors(green, blue), "  Green+Blue");
    printf("\n");
    
    // Invert colors
    printf("Inverted colors:\n");
    print_color(invert_color(red), "  ~Red   ");
    print_color(invert_color(green), "  ~Green ");
    print_color(invert_color(yellow), "  ~Yellow");
    printf("\n");
    
    // Grayscale
    printf("Grayscale conversion:\n");
    print_color(grayscale(red), "  Gray(Red)   ");
    print_color(grayscale(green), "  Gray(Green) ");
    print_color(grayscale(yellow), "  Gray(Yellow)");
    
    printf("\n");
}

// =============================================================================
// Example 9: Bit Array Implementation
// =============================================================================

typedef struct {
    uint8_t *bits;
    size_t num_bits;
    size_t num_bytes;
} BitArray;

BitArray* bitarray_create(size_t num_bits) {
    BitArray *ba = malloc(sizeof(BitArray));
    if (!ba) return NULL;
    
    ba->num_bits = num_bits;
    ba->num_bytes = (num_bits + 7) / 8;
    ba->bits = calloc(ba->num_bytes, 1);
    
    if (!ba->bits) {
        free(ba);
        return NULL;
    }
    
    return ba;
}

void bitarray_destroy(BitArray *ba) {
    if (ba) {
        free(ba->bits);
        free(ba);
    }
}

void bitarray_set(BitArray *ba, size_t index) {
    if (index < ba->num_bits) {
        ba->bits[index / 8] |= (1 << (index % 8));
    }
}

void bitarray_clear(BitArray *ba, size_t index) {
    if (index < ba->num_bits) {
        ba->bits[index / 8] &= ~(1 << (index % 8));
    }
}

bool bitarray_get(BitArray *ba, size_t index) {
    if (index >= ba->num_bits) return false;
    return (ba->bits[index / 8] >> (index % 8)) & 1;
}

void bitarray_toggle(BitArray *ba, size_t index) {
    if (index < ba->num_bits) {
        ba->bits[index / 8] ^= (1 << (index % 8));
    }
}

void bitarray_print(BitArray *ba) {
    printf("[");
    for (size_t i = 0; i < ba->num_bits; i++) {
        printf("%d", bitarray_get(ba, i) ? 1 : 0);
        if (i % 8 == 7 && i < ba->num_bits - 1) printf(" ");
    }
    printf("]\n");
}

int bitarray_count_set(BitArray *ba) {
    int count = 0;
    for (size_t i = 0; i < ba->num_bytes; i++) {
        count += count_set_bits(ba->bits[i]);
    }
    return count;
}

void example9_bit_array(void) {
    printf("=== Example 9: Bit Array Implementation ===\n\n");
    
    // Create a bit array with 32 bits
    BitArray *ba = bitarray_create(32);
    
    printf("Initial (all zeros):\n  ");
    bitarray_print(ba);
    
    // Set some bits
    printf("\nSetting bits 0, 5, 10, 15, 20, 25, 30:\n  ");
    bitarray_set(ba, 0);
    bitarray_set(ba, 5);
    bitarray_set(ba, 10);
    bitarray_set(ba, 15);
    bitarray_set(ba, 20);
    bitarray_set(ba, 25);
    bitarray_set(ba, 30);
    bitarray_print(ba);
    
    printf("  Count of set bits: %d\n", bitarray_count_set(ba));
    
    // Clear bit 15
    printf("\nClearing bit 15:\n  ");
    bitarray_clear(ba, 15);
    bitarray_print(ba);
    
    // Toggle bits 0-7
    printf("\nToggling bits 0-7:\n  ");
    for (int i = 0; i < 8; i++) {
        bitarray_toggle(ba, i);
    }
    bitarray_print(ba);
    
    // Check specific bits
    printf("\nChecking bits:\n");
    printf("  Bit 0: %s\n", bitarray_get(ba, 0) ? "SET" : "CLEAR");
    printf("  Bit 5: %s\n", bitarray_get(ba, 5) ? "SET" : "CLEAR");
    printf("  Bit 10: %s\n", bitarray_get(ba, 10) ? "SET" : "CLEAR");
    
    // Memory comparison
    printf("\nMemory efficiency:\n");
    printf("  32 bits using bit array: %zu bytes\n", ba->num_bytes);
    printf("  32 bools (bool[32]):     %zu bytes\n", 32 * sizeof(bool));
    printf("  32 ints (int[32]):       %zu bytes\n", 32 * sizeof(int));
    
    bitarray_destroy(ba);
    
    printf("\n");
}

// =============================================================================
// Example 10: XOR Tricks and Applications
// =============================================================================

void swap_without_temp(int *a, int *b) {
    *a ^= *b;
    *b ^= *a;
    *a ^= *b;
}

// Find the unique element (all others appear twice)
int find_unique(int arr[], int n) {
    int result = 0;
    for (int i = 0; i < n; i++) {
        result ^= arr[i];
    }
    return result;
}

// Simple XOR encryption
void xor_encrypt_decrypt(uint8_t *data, size_t len, uint8_t key) {
    for (size_t i = 0; i < len; i++) {
        data[i] ^= key;
    }
}

void example10_xor_tricks(void) {
    printf("=== Example 10: XOR Tricks and Applications ===\n\n");
    
    // Swap without temp
    printf("Swapping without temporary variable:\n");
    int a = 15, b = 27;
    printf("  Before: a = %d, b = %d\n", a, b);
    swap_without_temp(&a, &b);
    printf("  After:  a = %d, b = %d\n", a, b);
    printf("\n");
    
    // Find unique element
    printf("Finding unique element:\n");
    int arr[] = {2, 3, 5, 4, 5, 3, 4};
    int unique = find_unique(arr, 7);
    printf("  Array: {2, 3, 5, 4, 5, 3, 4}\n");
    printf("  Unique element: %d\n", unique);
    printf("\n");
    
    // XOR encryption
    printf("Simple XOR encryption:\n");
    char message[] = "Hello, World!";
    uint8_t key = 0x5A;
    
    printf("  Original:  \"%s\"\n", message);
    
    xor_encrypt_decrypt((uint8_t*)message, strlen(message), key);
    printf("  Encrypted: \"");
    for (size_t i = 0; i < strlen(message); i++) {
        printf("%02X ", (unsigned char)message[i]);
    }
    printf("\"\n");
    
    xor_encrypt_decrypt((uint8_t*)message, strlen(message), key);
    printf("  Decrypted: \"%s\"\n", message);
    printf("\n");
    
    // XOR properties demonstration
    printf("XOR properties:\n");
    printf("  x ^ 0 = x:       5 ^ 0 = %d\n", 5 ^ 0);
    printf("  x ^ x = 0:       7 ^ 7 = %d\n", 7 ^ 7);
    printf("  x ^ y ^ y = x:   9 ^ 3 ^ 3 = %d\n", 9 ^ 3 ^ 3);
    printf("  Commutative:     5 ^ 7 = %d, 7 ^ 5 = %d\n", 5 ^ 7, 7 ^ 5);
    printf("  Associative:     (3^5)^7 = %d, 3^(5^7) = %d\n", 
           (3 ^ 5) ^ 7, 3 ^ (5 ^ 7));
    
    printf("\n");
}

// =============================================================================
// Example 11: Practical Applications
// =============================================================================

// Check endianness
bool is_little_endian(void) {
    int i = 1;
    return *((char*)&i) == 1;
}

// Swap bytes in 16-bit value
uint16_t swap_bytes_16(uint16_t value) {
    return (value << 8) | (value >> 8);
}

// Swap bytes in 32-bit value
uint32_t swap_bytes_32(uint32_t value) {
    return ((value & 0xFF000000) >> 24) |
           ((value & 0x00FF0000) >> 8) |
           ((value & 0x0000FF00) << 8) |
           ((value & 0x000000FF) << 24);
}

// Calculate parity (even parity - returns 1 if odd number of 1s)
int parity8(uint8_t n) {
    n ^= n >> 4;
    n ^= n >> 2;
    n ^= n >> 1;
    return n & 1;
}

// Sign of integer without branching
int sign_of(int x) {
    return (x > 0) - (x < 0);
    // Alternative: return (x >> 31) - (-x >> 31);
}

// Absolute value without branching
int abs_no_branch(int x) {
    int mask = x >> 31;  // All 0s if positive, all 1s if negative
    return (x + mask) ^ mask;
}

void example11_practical_applications(void) {
    printf("=== Example 11: Practical Applications ===\n\n");
    
    // Endianness
    printf("System Endianness:\n");
    printf("  This system is %s-endian\n\n", 
           is_little_endian() ? "little" : "big");
    
    // Byte swapping
    printf("Byte Swapping:\n");
    uint16_t val16 = 0x1234;
    uint32_t val32 = 0x12345678;
    printf("  16-bit: 0x%04X -> 0x%04X\n", val16, swap_bytes_16(val16));
    printf("  32-bit: 0x%08X -> 0x%08X\n", val32, swap_bytes_32(val32));
    printf("\n");
    
    // Parity
    printf("Parity Calculation:\n");
    uint8_t parity_test[] = {0x00, 0x01, 0x03, 0x07, 0xFF, 0xAA};
    for (int i = 0; i < 6; i++) {
        printf("  parity(0x%02X) = %d (%d ones - %s parity)\n",
               parity_test[i], parity8(parity_test[i]),
               count_set_bits(parity_test[i]),
               parity8(parity_test[i]) ? "odd" : "even");
    }
    printf("\n");
    
    // Sign without branching
    printf("Sign of integer (no branching):\n");
    int sign_test[] = {-100, -1, 0, 1, 100};
    for (int i = 0; i < 5; i++) {
        printf("  sign(%d) = %d\n", sign_test[i], sign_of(sign_test[i]));
    }
    printf("\n");
    
    // Absolute value without branching
    printf("Absolute value (no branching):\n");
    int abs_test[] = {-50, -1, 0, 1, 50};
    for (int i = 0; i < 5; i++) {
        printf("  abs(%d) = %d\n", abs_test[i], abs_no_branch(abs_test[i]));
    }
    
    printf("\n");
}

// =============================================================================
// Example 12: Performance Optimizations
// =============================================================================

// Multiply by 10 using shifts and adds
int multiply_by_10(int n) {
    return (n << 3) + (n << 1);  // n*8 + n*2 = n*10
}

// Divide by power of 2 (for positive numbers)
int fast_divide_by_power_of_2(int n, int power) {
    return n >> power;
}

// Modulo by power of 2
int fast_mod_power_of_2(int n, int power_of_2) {
    return n & (power_of_2 - 1);
}

// Check if number has alternating bits (like 5: 101, 10: 1010)
bool has_alternating_bits(unsigned int n) {
    unsigned int xor_val = n ^ (n >> 1);
    return (xor_val & (xor_val + 1)) == 0;
}

// Count trailing zeros
int count_trailing_zeros(uint32_t n) {
    if (n == 0) return 32;
    int count = 0;
    while ((n & 1) == 0) {
        n >>= 1;
        count++;
    }
    return count;
}

// Count leading zeros
int count_leading_zeros(uint32_t n) {
    if (n == 0) return 32;
    int count = 0;
    while ((n & 0x80000000) == 0) {
        n <<= 1;
        count++;
    }
    return count;
}

void example12_performance_optimizations(void) {
    printf("=== Example 12: Performance Optimizations ===\n\n");
    
    // Fast multiplication
    printf("Fast multiplication by 10:\n");
    int mult_test[] = {0, 1, 5, 10, 25, 100};
    for (int i = 0; i < 6; i++) {
        printf("  %d * 10 = %d\n", mult_test[i], multiply_by_10(mult_test[i]));
    }
    printf("\n");
    
    // Fast division by power of 2
    printf("Fast division by power of 2:\n");
    printf("  100 / 2  = %d (shift by 1)\n", fast_divide_by_power_of_2(100, 1));
    printf("  100 / 4  = %d (shift by 2)\n", fast_divide_by_power_of_2(100, 2));
    printf("  100 / 8  = %d (shift by 3)\n", fast_divide_by_power_of_2(100, 3));
    printf("  100 / 16 = %d (shift by 4)\n", fast_divide_by_power_of_2(100, 4));
    printf("\n");
    
    // Fast modulo
    printf("Fast modulo by power of 2:\n");
    printf("  17 %% 8  = %d (AND with 7)\n", fast_mod_power_of_2(17, 8));
    printf("  25 %% 16 = %d (AND with 15)\n", fast_mod_power_of_2(25, 16));
    printf("  100 %% 32 = %d (AND with 31)\n", fast_mod_power_of_2(100, 32));
    printf("\n");
    
    // Alternating bits check
    printf("Alternating bits check:\n");
    uint32_t alt_test[] = {5, 10, 21, 42, 85, 7, 15};
    for (int i = 0; i < 7; i++) {
        printf("  %u (", alt_test[i]);
        for (int j = 7; j >= 0; j--) printf("%d", (alt_test[i] >> j) & 1);
        printf("): %s\n", 
               has_alternating_bits(alt_test[i]) ? "alternating" : "not alternating");
    }
    printf("\n");
    
    // Trailing and leading zeros
    printf("Counting zeros:\n");
    uint32_t zero_test[] = {1, 2, 4, 8, 16, 0x80, 0x80000000};
    for (int i = 0; i < 7; i++) {
        printf("  0x%08X: trailing=%d, leading=%d\n",
               zero_test[i],
               count_trailing_zeros(zero_test[i]),
               count_leading_zeros(zero_test[i]));
    }
    
    printf("\n");
}

// =============================================================================
// Main Function
// =============================================================================

int main(void) {
    printf("============================================================\n");
    printf("     BIT MANIPULATION IN C - COMPREHENSIVE EXAMPLES         \n");
    printf("============================================================\n\n");
    
    example1_bitwise_operators();
    example2_bit_shifting();
    example3_bit_manipulation();
    example4_bit_masks();
    example5_flags();
    example6_common_functions();
    example7_bit_fields();
    example8_color_manipulation();
    example9_bit_array();
    example10_xor_tricks();
    example11_practical_applications();
    example12_performance_optimizations();
    
    printf("============================================================\n");
    printf("                    END OF EXAMPLES                         \n");
    printf("============================================================\n");
    
    return 0;
}
Examples - C Programming Tutorial | DeepML