C按位或意外更改值

时间:2017-04-09 05:15:26

标签: c bitwise-operators bit-shift bitwise-or

我正在编写一个涉及二进制内存的程序,我需要在unsigned long long int中使用某个位序列。

现在,我正在循环遍历此代码块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]是一个char,它包含一个字节值,我将其转换为unsigned long long int,它似乎正在我可以告诉的工作,直到我得到一个奇怪的bug。 例如,以下是二进制形式的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对我来说已经足够了。 如果需要更多信息和背景,请告诉我。

谢谢!

1 个答案:

答案 0 :(得分:2)

类型char可以是unsigned signed,具体取决于编译器。在您的情况下,它似乎是signed

这意味着当您将其转换为更大的类型时,您会遇到名为 sign extension 的内容。您在二进制数中看到的所有内容都是由于这一点以及two's complement(处理负数的最常用方式)的工作原理。

如果要存储无符号的小8位值,请使用显式uint8_t类型(注意u前缀,代表unsigned)。参见例如this fixed-width integer reference了解更多信息。