2011-10-13 6 views
1

나는 잠시 동안 팩을 시도했습니다. & 정수로 일부 문자를 압축 해제했습니다. 이 질문과 관련된 몇 가지 주제가 있지만, 내 문제는 서명 된 교대와 관련이 있습니다. 나는 서명 값, 즉 압축을 해제하기 위해 '트릭'을하지 않습니다부호가있는 데이터를 사용하여 비트 단위로 풀기

예상대로 작동하지만
char c1 = -119; 
char c2 = 26; 

// pack 
int packed = (unsigned char)c1 | (c2 << 8); 
// unpack 
c1 = packed >> 0; 
c2 = packed >> 8; 

// printf(c1, c2) -> Unpacked data: -119 | 26 

나는 더 많은 데이터, 즉 포장하려고하면

char c0 = -42; 
char c1 = -119; 
char c2 = 26; 

// pack 
int packed = (unsigned char)c0 | (unsigned char)(c1 << 8) | (c2 << 16); 
// unpack 
c0 = packed >> 0; 
c1 = packed >> 8; 
c2 = packed >> 16; 

// printf -> Unpacked data: -42 | 0 | 26 

C1 값을 놓친다. 나는 그것이 과 관련이 있다고 생각합니다. 부호 비트가 상위 위치 인으로 옮겨졌습니다.

어떻게 돌아갈 수 있습니까? c1 값이 있습니까?

미리 감사드립니다.

답변

4

당신은 해당 유형의 범위 밖으로 이동 c1unsigned char에 캐스팅, 그래서 캐스트의 결과는 0입니다. 당신은 이동하기 전에 캐스트를 수행해야합니다

int packed = (unsigned char)c0 | ((unsigned char)c1 << 8) | (c2 << 16); 
+0

좋은 설명 :) 의심의 여지가 없습니다. 감사합니다! – pQB

2
(unsigned char)(c1 << 8) 

  • 변화 잘못된 (로그인 확장) 값
  • (0 항복) 8 비트
  • 에 결과를 손질한다

아무 것도 원하지 않으므로 ((unsigned char)c1 << 8)을 사용해야합니다.

+0

무효. Signed to unsigned 형 변환은 형식이 얼마나 넓거나 좁든지 상관없이 정의되지 않은 동작입니다. (unsigned to signed로 변환하는 것과는 대조적입니다.) 코드는 여전히 잘못되었지만 UB가 아닙니다. – Nemo

+0

@ 니모 : 니 말이 맞아, 내가 무슨 생각을했는지 궁금해. – jpalecek

0

일부 int은 16 비트입니다. 휴대용이 코드는 int32_t을 사용하십시오.

int32_t packed = ((uint8_t)c0) | (((uint8_t)c1)<<8) | (((uint8_t)c2) << 16); 

가 나는 또한 역순으로이 목록을하는 경향이있다, 그래서 문자가 대부분 최하위 바이트이되는 자연이다 : 올바른 방법입니다 (약간의 편집증 경우)이 작업을 수행합니다.

관련 문제