2011-06-10 4 views
4

C++에서 부호없는 시프트를하고 싶습니다. 여기에 예제 코드가있다. 문제는 그것이 일반적이지 않다는 것입니다. 이 코드는 완전히 잘못되었습니다. longs에서는 작동하지 않으며 char과 같은 더 작은 유형에서는 작동하지 않습니다. 나는 (unsigned T)을 시도했지만 구문 오류입니다. 전문화하지 않고 어떻게 일반화 할 수 있습니까?C++에서 부호없는 시프트 템플리트

#include <cassert> 
template<class T> 
T unsigned_shift(const T&t, int s) { return ((unsigned int)t)>>s; } 
int main() 
{ 
    assert(unsigned_shift(-1, 2)==(-1u>>2)); 
    assert(unsigned_shift((char)-1, 2)==64); 
} 

답변

6

Boost을 사용할 수있는 경우 type_traits 라이브러리에는 필요에 완벽하게 맞는 make_unsigned 템플릿이 있습니다.

+0

부스트를 사용할 수 있는지 확신 할 수 없지만 코드를 살펴본 결과 전문화를 사용해야합니다. 나중에 C++ 0x 사람이 다른 대답을 추가 할 수 있기를 기대하면서 나중에 받아 들일 것입니다. –

+1

@ acidzombie24'std :: make_ [서명되지 않은]이 (가) C++ 0x와 함께 '' . 그들의 사양은 Boost 특성과 유사합니다. 마지막으로, 리턴 될 때 부호없는 (unsigned)에서 T 로의 최종 (묵시적인) 변환은 T가 서명 될 때 정의 된 구현임을 기억하십시오. –

+0

@Luc : 고맙습니다. –

0

어떤 변화를 할 unsigned long에 캐스팅 한 후 그것을 돌려 다시 T에 캐스팅에 대해?

또한 정상적인 2의 보완에서 두 번째 교대의 결과는 64가 아닌 63이 될 것입니까?

+0

오는 단 (63) 일 것이다를 잘 -

#include <boost/type_traits/make_unsigned.hpp> template<class T> T unsigned_shift(const T&t, unsigned int s) { return ((make_unsigned<T>::type)t)>>s; } 

은 (¶1 §5.8 참조 시프트 연산자의 동작은 상기 제 2 피연산자의 음수 값 정의되지 때문에 unsigned ints의 종류를 변경) unsigned long에 -1을 설정하면 모든 비트가 설정되므로 >> 1이 여전히 -1이됩니다. –

+1

부호가 1 인 모든 집합이 음수가 아닙니다. 이 유형에 대해 가능한 가장 큰 값입니다. – Jay

관련 문제