2010-01-19 3 views
1

비트 회전 함수를 쓰려고하는데 sizeof 연산자에 대한 설명이 더 필요합니다. 내가 회전 할 필요가 수치 객체의 유형을 알 수 없기 때문에, 내가sizeof 연산자를 사용하여 회전 비트

unsigned rotator(unsigned object, int count) 

객체가 회전하는 물체 카운트는이 함수 프로토 타입의를 sizeof 연산자를 사용할 필요가 가정하는 것은의 수 이동할 비트. 나는 8 비트 번호가 있다면, 내가 먼저 사람이 예를 들어 카운트 = 20을 만들 수 있기 때문에 실제 비트 수 (회전 수를 결정 것이라고 상상하고, 그래서 나는 같은 것을 할 것 :

int actualBitRotation; 
if (count > sizeof(object)) { 
    actualBitRotation = count % sizeof(object); 

을 그러나 나는 정확하게 sizeof를 이해하고 있다고 생각하지 않습니다. 나는 그것에 대한 온라인 자료를 읽으려고했는데 또 다른 문제로이 게시판에서 도움을 받았지만 얻지 못할 것이라고 생각합니다. sizeof가 숫자를 반환한다는 것을 알고 있습니다. 그래서이 포함됩니다 대신 뭔가 할 객체의 바이트, 더 같은

int actualBitRotation; 
if (count > (sizeof(object) * CHAR_BIT) { 
    actualBitRotation = count % (sizeof(object) * CHAR_BIT); 
} 

감사합니다!

답변

3

sizeof()는 바이트 수를 반환하므로 비트 수를 얻기 위해 CHAR_BIT를 곱해야합니다.

template<typename T> T bitrot(T& t,size_t bits) { 
    bits %= (sizeof(T)*CHAR_BIT); 
    return ((t >> (sizeof(T)*CHAR_BIT)-bits) | (t << bits)); 
} 

명확하게하기 위해 변수의 비트 수를 초과하여 작업을 이동하지 마십시오. 결과는 프로세서 및 컴파일러에 따라 다릅니다.

+0

나는 크리스탈 당신이 INT의 비트 수 후 더 회전하면 어떻게되는지에 대해 질문했다 생각합니다. bitrot() 함수의 시작 부분에 다음 코드를 넣으십시오. bits = bits % (sizeof (T) * CHAR_BITS); – dkantowitz

+0

실제로, 시프트는 형식의 너비보다 작아야합니다. 따라서 bits = 0 일 때 실제로 위의 문제가 발생했습니다. 보통 >> 32는 pentiums에서 n >> 0과 같기 때문에 '|' 숨 깁니다. 원래 K & R (사본을 잃어 버렸습니다)에서 교대는 <= 너비로 허용되었지만 더 최근의 것은 <너비 여야합니다. 누구도 오래된 K & R을 가지고 있니? Intel의 첫 번째 가변 시프트 연산 (80186에서)은 CL의 5LSB를 조사했기 때문에 궁금합니다. 따라서 16 비트 값의 시프트는 0에서 16 비트로 이루어졌습니다. 386 그들은 32 비트 regs 5 비트에서 그것을 떠났다. 인텔이 C를 깨뜨 렸니? – greggo

0

는 방법에 대해 :

union hack { 
    int asSigned; 
    unsigned asUnsigned; 
}; 
hack top, bottom; 
int realBitCount = count % (sizeof(T)*8); 
top.asSigned = (realBitCount == 0) ? 0 : -(1 << (realBitCount-1)); 
bottom.asUnsigned = 0xFFFFFFFF^top.asUnsigned; 

top.asUnsigned &= object; 
bottom.asUnsigned &= object; 
return static_cast<T>((bottom.asUnsigned << realBitCount) | (top.asUnsigned >> (sizeof(T)-realBitCount))); 
관련 문제