2014-03-06 2 views
0

안녕하세요.이 모든 것이 간단한 바보 같은 질문이 될 수 있지만, 지금 당황 스럽습니다. Named Binary Tag 파일에서 데이터를 읽었으며 빅 엔디안 숫자를 읽으려고 할 때를 제외하고 코드가 작동합니다. 내가 얻는 값은 어떤 이유로 지금파일에서 이진수를 읽는 것은 음수가됩니다.

이 코드는 원래 일
void NBTTypes::readData(istream &in, char *buffer, unsigned long num_bytes, bool BE) 
{ 
    char hold; 

    //get data 
    in.read(buffer, num_bytes); 

    if(BE) 
    { 
     //convert to little-endian 
     cout <<"Converting to a little-endian number..." << endl; 
     for(unsigned long i = 0; i < num_bytes/2; ++i) 
     { 
      hold = buffer[i]; 
      buffer[i] = buffer[num_bytes - i - 1]; 
      buffer[num_bytes - i - 1] = hold; 
     } 
     cout <<"Done." << endl; 
    } 
} 

가 (정확한 양의 값을 주었다), 그러나 :

long NBTTypes::getInteger(istream &in, int num_bytes, bool isBigEndian) 
{ 
    long result = 0; 
    char buff[8]; 

    //get bytes 
    readData(in, buff, num_bytes, isBigEndian); 

    //convert to integer 
    cout <<"Converting bytes to integer..." << endl; 
    result = buff[0]; 
    cout <<"Result starts at " << result << endl; 
    for(int i = 1; i < num_bytes; ++i) 
    { 
     result = (result << 8) | buff[i]; 
     cout <<"Result is now " << result << endl; 
    } 
    cout <<"Done." << endl; 

    return result; 
} 

그리고되어, readData 기능 : 정수를 가져옵니다 코드는 다음과 같습니다 오버 또는 언더 플로우 중. 내가 뭘 놓치고 있니?

+0

? 번호가 너무 길어서 오래 나타낼 수 없습니까? 대신 unsigned long을 시도하십시오. – TripShock

+0

'isBigEndian'의 설정을 포함하여'readData'에 대한 입력과 출력의 예제를 보여줍니다. –

+0

의견을 보내 주셔서 감사합니다. 내가 예상하는 번호는 128이지만 대신 -128을 얻습니다. 바이너리 입력은 빅 엔디안 short (128)입니다. 반환 된 바이트는 정답을 얻어야합니다. –

답변

1

바이트 순서 스와핑은 문제가 없지만 바이트 시퀀스에서 정수를 작성하는 것은 아닙니다.

우선, endianness가 잘못되었습니다. 첫 번째 바이트는 가장 중요한 바이트가되고 다른 바이트는 가장 가까운 바이트가됩니다. 배열에서 문자 -ing 때 OR

그런 다음, 당신이 그들을 마스크하지 않는 한 그들이 char 서명에 대한 추가 비트를 많이 설정, int, 승진 것을주의해야합니다.

마지막으로 longnum_bytes보다 넓은 경우 sign-extend 비트가 필요합니다.

이 코드는 작동 : 숫자가 무엇을 기대하고있다

union { 
    long s;   // Signed result 
    unsigned long u; // Use unsigned for safe bit-shifting 
} result; 

int i = num_bytes-1; 
if (buff[i] & 0x80) 
    result.s = -1; // sign-extend 
else 
    result.s = 0; 
for (; i >= 0; --i) 
    result.u = (result.u << 8) | (0xff & buff[i]); 
return result.s; 
+0

이 대답에 감사드립니다. 나는 표지 확장이나 마스킹을 생각하지 못했습니다! 나는 이제 Minecraft 프로그래밍에 대한 나의 노력에서 한 걸음 가까이 다가 간다. :) –