2010-07-12 4 views
1

배열이 unsigned chars입니다. 기본적으로 비트 배열이 있습니다. u30 - variable length encoded 30-bit unsigned integer value :C++ 기본 데이터 유형 : 부호없는 30 비트를 읽는 방법

제가 처음 16 비트 부호없는 정수에 해당하는지 알고 난 (u16)(*(buffer+ 1) << 8 | *abcBuffer)

를 이용하여 그 값을 검색이어서 다음과 같이 설명한다 u30라는 데이터 타입 온다. u30의 가변 인코딩은 인코딩 된 값의 크기에 따라 1에서 5 바이트를 사용합니다. 각 바이트는 그 값에 대해 하위 7 비트를 제공합니다. 바이트의 상위 (8 번째) 비트가 설정되면 다음 바이트도 값의 일부입니다.

이 설명을 이해할 수 없습니다 : u30 (30!)이라고 말하면 1에서 5 바이트라고 말합니까? 또한 s24 - three-byte signed integer value.이라는 데이터 유형이 있습니다.

비표준 데이터 유형을 읽는 방법 (값을 검색하는 방법)은 무엇입니까? 어떤 도움을 주시면 감사하겠습니다.

고맙습니다.

+2

각 바이트의 7 비트 만 사용하기 때문에 1에서 5 바이트이므로 4 바이트는 28 비트 만 나타낼 수 있습니다. 30 비트 값을 나타 내기 위해서는 5 바이트가 모두 필요합니다. –

+0

여기가 어디입니까? DEC의 PDP-10과 같은 오래된 아키텍처는 6 비트 바이트를 사용했습니다. –

+0

5 * 7 = 30 여기에 혼란은 보이지 않습니다. 귀하의 질문에 대답 : 귀하의 두통을 치료하기 위해 저렴한 테킬라의 5와 함께. –

답변

2

나는 (정확하게 의문의 여지가있는) 올바르게 이해한다고 가정하고, 다음은 값을 읽을 것입니다.

unsigned int val; 
    unsigned char buf[300]; 
    int i; 
    int shift; 

    i = 0; 

    buf[0] = 0x81; 
    buf[1] = 0x3; 
    val = 0; 
    shift = 0; 
    do 
     { 
     val |= (0x7F & buf[i]) << shift; 
     shift += 7; 
     i++; 
     } while ((buf[i-1] & 0x80) && (i < 5)); 
    printf("Val = %u\n", val); 
+0

5 번째 바이트에 너무 많은 비트가있는 경우를 감지하기 위해 오류 검사를 추가 할 수 있습니다. 따라서 결과가 30 비트에 맞지 않습니다? –

+0

OP에서 모호한 것은 "기계"가 크거나 작은 엔디안인지 여부입니다. 빅 엔디안이라면 현재 바이트를 n * 7 번 위로 이동하는 대신 루프를 통해 매번 7 번씩 val을 이동하면됩니다. 바이트 5의 최상위 6 비트가 설정되어 있다면 (David의 말처럼) 어떤 일이 일어나야하는지 궁금해해야합니다. –

+0

endian-ness에 대한 귀하의 요점은 정확합니다. 나는 그것에 대해 생각해 보았고 (쉽게 말하면) 쉬운 길을 택했습니다. 나는 단지 내가 어떻게 인코딩을 작성했는지 (7 개의 하위 비트 쓰기), 오른쪽으로 이동, 다음 7 비트 추출 등을 기반으로 추측을했다. –

1

인코딩 포맷 설명은 아마도 약간 비공식적이지만 충분해야한다 :이 실시 예에서 위치 0에서 시작 (i 버퍼의 실제 위치에 의해 오프셋 될 필요가있다). 아이디어는 당신이 1 바이트를 읽는다는 것입니다 (x이라고 부름). 가장 낮은 비트가 설정되어 있는지 확인하기 위해서 가장 낮은 비트 인 7 비트를 x & 0x7F으로 가져 가야합니다. 현재의 바이트가 더 이상 최상위 비트를 갖지 않을 때까지 uint 변수에 7 비트 시퀀스를 병합하는 작은 루프를 작성해야합니다.

새로운 비트를 하이 엔드에 병합해야하는지 아니면 로우 엔드 (a = (a << 7) | (x & 0x7F))에 병합해야하는지 파악해야합니다. 이를 위해서는 올바른 출력이 무엇인지 알 수있는 테스트 시퀀스가 ​​필요합니다.

4
i=0;  
val = buf[i]&0x7F; 
while (buf[i++]&0x80) 
{ 
    val |= (buf[i]&0x7F)<<(i*7); 
} 
0

가변 길이 30 비트 값을 읽으려면, 당신은 같은 것을 할 수있는 :

const char HIGH_BIT = 0x80; 
const char DATA_MASK = 0x7F; 
const char LAST_MASK = 0x03; // only need 2 bits of last byte 
char tmpValue = 0; // tmp holder for value of byte; 
int value = 0; holder for the actual value; 
char* ptr = buffer; // assume buffer is at the start of the 30 bit number 
for(int i = 0; i < 5; i++) 
{ 
    if(i == 4) 
    { 
     tmpValue = LAST_MASK & *ptr; 
    } 
    else 
    { 
     tmpValue = DATA_MASK & *ptr; 
    } 

    value |= tmpValue << (7 * i); 

    if(!(HIGH_BIT & *ptr)) 
    { 
     break; 
    } 
    if(i != 4) 
    { 
    ++ptr; 
    } 
} 
buff = ptr; // advance the buffer afterwards. 

@ 마크 : 당신의 대답은 내가이 입력하는 동안 게시하고, 높은 제외한 작동합니다 바이트. 값은 30 비트이므로 상위 바이트의 처음 2 비트 만 값으로 사용되며 전체 8 비트 값을 사용하고 있습니다.

+0

예 - 실제로 나는 그 비트 (heh heh) 그것을 고칠 다시. –