회전(회전/원형) 이동 작업은 특정 비트 수만큼 숫자의 비트를 이동시키고 떨어진 비트를 반대쪽 끝으로 옮기는 것입니다. C 언어에는 이 작업을 위한 내장 연산자가 없습니다. 이러한 결정은 역사적으로 표준 라이브러리의 이식성과 다양한 플랫폼에 대해 동작을 명시적으로 정의할 필요성과 관련이 있습니다.
문제는 표준 이동 연산자(<<, >>)는 이동을 회전 방식으로 수행하지 않으며, 단순히 비트를 이동시키고 "떨어진" 비트를 0으로 대체한다는 것입니다. 회전 이동을 수행하기 위해서는 두 개의 이동 결과를 명시적으로 조합하고 지정된 비트 수만큼 결과를 마스킹해야 합니다.
해결책은 수동으로 회전 이동을 구현하는 것입니다. 32비트 부호 없는 정수에 대한 구현은 다음과 같습니다:
uint32_t rotate_left(uint32_t value, unsigned int shift) { return (value << shift) | (value >> (32 - shift)); } uint32_t rotate_right(uint32_t value, unsigned int shift) { return (value >> shift) | (value << (32 - shift)); }
주요 특징:
<< 또는 >> 연산자가 추가적인 연산 없이 회전 이동을 구현할 수 있나요?
아니요. 일반적인 이동은 경계를 넘어간 비트를 0으로 대체하여 다른 쪽으로 옮기지 않습니다.
타입의 크기만큼 이동을 하면(shift가 숫자의 비트 수와 같을 경우) 어떤 일이 발생하나요?
동작이 정의되지 않습니다(Undefined Behavior와 관련, C 표준에 따르면). 항상 데이터 타입 크기에 대해 모듈로를 적용하여 이동해야 합니다.
부호 있는 타입에 대해 이 함수를 사용하여 회전 이동을 안전하게 수행할 수 있나요?
아니요, 항상 부호 없는 타입을 사용해야 합니다. 부호 있는 타입의 비트 이동은 컴파일러와 아키텍처에 따라 다르게 동작하므로 주의해야 합니다.
회전 이동을 위해 일반 이동을 사용하는 경우:
uint32_t x = 0xFA3C0F00; uint32_t y = x << 5; // 회전 이동이 아님
장점:
단점:
타입 크기와 UB 보호를 고려한 수동 함수 회전 이동을 사용하는 경우:
uint32_t x = 0xFA3C0F00; uint32_t y = rotate_left(x, 5);
장점:
단점: