Acc*_*tor 0 c c++ bit-manipulation bit-shift bit
我用这个代码将4个2位值(无符号字符但它们只保存0-3的值)组合成1个单个无符号字符值
unsigned char nibble = 0;
nibble = (nibble & 0x03) | (output[i] & 0x03);
nibble = (nibble & 0x0C) | (output[i+1] & 0x03) << 2);
nibble = (nibble & 0x30) | (output[i+2] & 0x03) << 4);
nibble = (nibble & 0xC0) | (output[i+3] & 0x03) << 6);
Run Code Online (Sandbox Code Playgroud)
它会为除00 00 00 00之外的所有内容生成不正确的值(它通常会为2个不同的2位值组生成相同的结果).
我很困惑,因为上面的代码是这段代码的编辑,可以很好地将2个4位值组合成1个字节,那么为什么我的版本不能将4个2位值组合成1个字节呢?
char byte;
byte = (byte & 0xF0) | (nibble1 & 0xF); // write low quartet
byte = (byte & 0x0F) | ((nibble2 & 0xF) << 4); // write high quartet
Run Code Online (Sandbox Code Playgroud)
我已经尝试将0x03/0x0C/0x30/0xC0更改为0xC0/0x30/0x0C/0x03,仍然是错误的.将0x03更改为&0xC0也是如此.
这是因为你每次都清除了半字节中的位.
也就是说,当你这样说:
nibble = (nibble & 0xC0)
Run Code Online (Sandbox Code Playgroud)
你真正说的是"扔掉我到目前为止所做的所有工作,除了第3和第4位的位".
此代码(未经测试)可能会解决您的问题:
unsigned char nibble = 0;
nibble |= (output[i ] & 0x03);
nibble |= (output[i+1] & 0x03) << 2;
nibble |= (output[i+2] & 0x03) << 4;
nibble |= (output[i+3] & 0x03) << 6;
Run Code Online (Sandbox Code Playgroud)
如果这是真的真的,output[i+x]只有在范围内拥有值[0,3] ,那么您可以按如下更改代码:
unsigned char nibble = 0;
assert(0<=output[i ] && output[i ]<=3)
nibble |= output[i ];
assert(0<=output[i+1] && output[i+1]<=3)
nibble |= output[i+1] << 2;
assert(0<=output[i+2] && output[i+2]<=3)
nibble |= output[i+2] << 4;
assert(0<=output[i+3] && output[i+3]<=3)
nibble |= output[i+3] << 6;
Run Code Online (Sandbox Code Playgroud)
当然,如果你真的非常肯定的话,可以删除这些断言.但是你也可以让它们进入并让编译器通过使用NDEBUGflag(g++ -DNDEBUG mycode.cpp)来消除它们.有关详细信息,请参阅此问题.
| 归档时间: |
|
| 查看次数: |
600 次 |
| 最近记录: |