2017-04-09 11 views
1

현재 이진 메모리가 포함 된 프로그램을 작성하고 있으며 부호없는 long long int에 특정 비트 시퀀스가 ​​필요합니다.C 예상치 않게 비트 단위 OR 값 변경

지금 당장은이 코드 블록을 4 번 반복하여 32 비트 시퀀스를 만들려고합니다.

unsigned long long int currentEntry = 0; 
for (int j = 0; j < 4; ++j){ 
    currentEntry = (currentEntry << 8); 
    currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); 
} 

는 entrybuffer [I] [J] 나는 이상한 얻을 수 있습니다 내가 부호 오래 오래 INT에 던져 바이트 값을 포함, 그것은 지금까지 내가 말할 수있는 작동하는 것처럼 보이는 문자까지 곤충. 예를 들어, 여기 바이너리 형태로 currentEntry 변수입니다 :

//goal bit sequence: 00001000000001001010000011000000 

currentEntry = (currentEntry << 8); 
//00000000 
currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); //entrybuffer[i][j] = 00001000 
//00001000 
currentEntry = (currentEntry << 8); 
//0000100000000000 
currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); //entrybuffer[i][j] = 00000100 
//0000100000000100 
currentEntry = (currentEntry << 8); 
//000010000000010000000000 
currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); //entrybuffer[i][j] = 10100000 
//111111111111111110100000 (what?)***** 
currentEntry = (currentEntry << 8); 
//11111111111111111010000000000000 
currentEntry = (currentEntry | (unsigned long long int)entryBuffer[i][j]); //entrybuffer[i][j] = 11000000 
//11111111111111111111111111000000 

내가 여기 분명 뭔가 빠진 것 같다, 그리고 누군가가 나에게이 문제를 알아내는 데 도움이 할 수 있는지 궁금하네요. 코드가 충분히 이해되기를 바랍니다.

분명히 비트 OR이 뭔가를 변경하고 있거나 어딘가에서 넘쳐 흐르고 있기 때문에 currentEntry를 부호없는 long long int로 변경 한 것입니다. 분명히 4 바이트의 저장 공간 만 필요합니다. 그리고 이것은 기계마다 다르다는 것을 이해합니다. 그러나 서명되지 않은 long long int는 제 목적을 위해 충분할 것이라고 생각했습니다. 자세한 정보와 상황이 필요한 경우 알려 주시기 바랍니다.

감사합니다.

+0

경고와 함께 컴파일하고 있지 않습니다 (예 :'-Wall -Wextra')? * 엄격한 앨리어싱 * 규칙? –

+0

무엇이 *'entryBuffer'입니까? 그 * 유형 *은 무엇입니까? –

+0

@ 일부 프로그래머는 entryBuffer는 char입니다. 나는 또한 경고로 컴파일하고 있지만 엄격한 앨리어싱 규칙은 생각하지 않습니다. – storm143

답변

2

유형 char 컴파일러에 따라 하나 또는 unsignedsigned 수있다. 귀하의 경우에는 signed 인 것으로 보입니다.

즉, 더 큰 유형으로 캐스팅하면 부호 확장이라는 것을 발견하게됩니다. 이진수에 표시되는 모든 것은 그 때문이고 어떻게 음수를 처리하는 가장 일반적인 방법 인 two's complement이 작동하는지 때문입니다.

부호없는 작은 8 비트 값을 저장하려는 경우 명시적인 uint8_t 유형을 사용하십시오 (unsigned 인 접두어 u에 유의하십시오). 예 : 자세한 내용은 this fixed-width integer reference을 참조하십시오.

+2

실제로 longlong으로 확장 한 후 char이 0xFF에 대해 마스크 된 경우 실제로 작동합니다. – davidbak

+0

@ 일부 프로그래머 임마 감사합니다! 그거야. 오늘 새로운 것을 배웠습니다. 나는 그것이 2의 보완법과 관련이 있다는 것을 알았지 만, char 타입이 signed 나 unsigned 일지는 몰랐다. 나는 entryBuffer를 (unsigned long long int) (uint8_t) entryBuffer [i] [j]로 캐스팅하는 것을 끝내었다. – storm143