Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม C

โปรแกรม C หมุนบิต (Rotate Bits) ซ้าย/ขวา

Bit Rotation (Circular Shift)** คือการเลื่อนบิต โดยบิตที่หลุดออกด้านหนึ่ง จะวนกลับมาอีกด้านหนึ่ง แตกต่างจาก Shift ปกติที่บิตหลุดจะหายไป

ประเภทการหมุน

  • Left Rotate: บิต MSB วนไป LSB
  • Right Rotate: บิต LSB วนไป MSB

ตัวอย่าง: 12 (00001100) Left Rotate 2

Before: 0000 1100
Step 1: 0001 1000  (MSB=0 → LSB)
Step 2: 0011 0000  (MSB=0 → LSB)
After:  0011 0000 = 48

ตัวอย่าง: 18 (00010010) Right Rotate 2

Before: 0001 0010
Step 1: 0000 1001  (LSB=0 → MSB)
Step 2: 1000 0100  (LSB=1 → MSB)
After:  1000 0100 = 132 (unsigned) / -124 (signed 8-bit)

โค้ด Left Rotate

#include <stdio.h>
#include <stdint.h>
#include <limits.h>

uint32_t leftRotate(uint32_t n, unsigned int r) {
    int width = sizeof(n) * CHAR_BIT;  // 32
    r %= width;                        // Handle r >= width
    return (n << r) | (n >> (width - r));
}

int main() {
    uint32_t num, rot;
    printf("Enter number: ");
    scanf("%u", &num);
    printf("Enter rotations: ");
    scanf("%u", &rot);
    
    uint32_t result = leftRotate(num, rot);
    printf("Left Rotate: %u (0x%08X)\n", result, result);
    return 0;
}

โค้ด Right Rotate

uint32_t rightRotate(uint32_t n, unsigned int r) {
    int width = sizeof(n) * CHAR_BIT;
    r %= width;
    return (n >> r) | (n << (width - r));
}

โค้ดรวม (Generic Rotate)

#include <stdio.h>
#include <stdint.h>
#include <limits.h>

uint32_t rotateLeft(uint32_t x, int n) {
    int w = sizeof(x) * CHAR_BIT;
    n = n % w;
    return (x << n) | (x >> (w - n));
}

uint32_t rotateRight(uint32_t x, int n) {
    int w = sizeof(x) * CHAR_BIT;
    n = n % w;
    return (x >> n) | (x << (w - n));
}

void printBits(uint32_t x) {
    for(int i = 31; i >= 0; i--)
        putchar((x >> i) & 1 ? '1' : '0');
    printf("\n");
}

int main() {
    uint32_t num;
    int rot;
    
    printf("Enter 32-bit number: ");
    scanf("%u", &num);
    printf("Enter rotation count: ");
    scanf("%d", &rot);
    
    printf("\nOriginal:  "); printBits(num);
    
    uint32_t left = rotateLeft(num, rot);
    printf("Left %2d:  ", rot); printBits(left);
    printf("Decimal: %u\n", left);
    
    uint32_t right = rotateRight(num, rot);
    printf("Right %2d: ", rot); printBits(right);
    printf("Decimal: %u\n", right);
    
    return 0;
}

ผลลัพธ์

Enter 32-bit number: 12
Enter rotation count: 2

Original:  00000000000000000000000000001100
Left  2:   00000000000000000000000000110000
Decimal: 48
Right  2:  00000000000000000000000000000011
Decimal: 3

การใช้งานจริง

  • Cryptography - AES, SHA, RC4 ใช้ Rotate มาก
  • Hash Functions - Jenkins, MurmurHash
  • Compression - Bit Packing
  • Graphics - Pixel Manipulation
  • Embedded - Register Manipulation

Built-in (GCC/Clang C23+)

// C23 Standard
#include <stdbit.h>

uint32_t x = 12;
uint32_t left = stdc_rotl(x, 2);   // Left rotate
uint32_t right = stdc_rotr(x, 2);  // Right rotate

⚠️ หมายเหตุสำคัญ

  • ใช้ Unsigned Types (uint32_t) เพื่อหลีกเลี่ยง Sign Extension
  • Rotation Count ต้อง Mod ด้วย Bit Width (ป้องกัน UB)
  • C ก่อน C23 ไม่มี Standard Rotate ต้องเขียนเองหรือใช้ Built-in