2011-02-14 2 views
2

나는 예를 들어 바이트에서 3 비트 값 정확한하기 위해 노력하고있어 :병합 bitshifts

unsigned char r = ((253 << 5) >> 5); 

결과 값이 5해야을하지만 왜 그것은 253를 반환합니까?

+1

왜 비트 마스크를 사용하여 3 LSB - 00000111b를 제거하지 않으십니까? – StuartLC

+0

왼쪽 비트를 이동하면 5가되지만 마스크는 가능합니다. – CashCow

답변

8

두 가지 가능성 :

  • 귀하의 표현은 정수로 평가되고 마지막에 sngle 바이트 값으로 캐스팅.
  • 컴파일러가 시프트 연산을 최적화합니다. 당신의 결과는 5,해야

참고하지 3. 당신이 원하는 것은 :

const unsigned char c = 253 & 0x07 ; // (00000111) 

귀하의 비트 마스크는 다음과 같습니다

253 | 1 1 1 1 1 1 0 1 | F D 
    7 | 0 0 0 0 0 1 1 1 | 0 7 
+++++++++++++++++++++++++++ 
    5 | 0 0 0 0 0 1 0 1 | 0 5 
1

때문에 정수 추진. 바이트 단위로만 작동하도록 제한하는 표현식은 253 << 5입니다. 리터럴 253의 유형은 int입니다.

마스크를 사용하여 캐스트를 추가하거나 (필자 의견으로는) 추출해야합니다. 정수에서 가장 낮은 3 비트를 얻을하려면 사용 : 1 < < 3 진수로 00001000 인 8 때문에

const unsigned char r = 253 & ~((1 << 3) - 1); 

이 작동합니다. 우리는 하나를 빼서 7을 얻습니다. 또는 00000111 . 우리는 이것을 뒤집어 3 개의 가장 오른쪽 비트, 즉 11111000 을 제외한 모든 것을 포함하는 마스크를 얻습니다. 그런 다음 추출을 수행 할 값과 비트 단위로 결합됩니다.

위의 예에서는정밀도를 사용했기 때문에 8 비트 만 사용하여 이진 값을 표시하고 플랫폼의 int 크기까지는 0으로 왼쪽으로 확장합니다.

3

표현식은 int를 사용하여 계산됩니다. 변경 :

unsigned char r = ((unsigned char)(253 << 5) >> 5); 

원하는 결과를 얻으실 수 있습니다.