首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将4位2位值合并为1 8位值?

如何将4位2位值合并为1 8位值?
EN

Stack Overflow用户
提问于 2017-08-10 01:52:49
回答 2查看 1.5K关注 0票数 0

此代码用于将4个2位值(无符号字符,但它们只保存从0-3到1个无符号字符值)组合为1个无符号字符值。

代码语言:javascript
复制
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);

它为除00 00 00以外的所有事物产生一个不正确的值(它通常对2组不同的2位值产生相同的结果)。

我很困惑,因为上面的代码是this code的编辑,它可以很好地将2位值组合成1字节,那么为什么我的版本不将4位值组合成1字节呢?

代码语言:javascript
复制
char byte;
byte = (byte & 0xF0) | (nibble1 & 0xF); // write low quartet
byte = (byte & 0x0F) | ((nibble2 & 0xF) << 4); // write high quartet

我尝试过将0x03 / 0x0C / 0x30 / 0xC0更改为0xC0 / 0x30 / 0x0C / 0x03,但仍然错误。同样,将& 0x03更改为& 0xC0。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-10 01:56:19

这是因为你每次都会清除咬碎的碎片。

也就是说,当你这样说:

代码语言:javascript
复制
nibble = (nibble & 0xC0)

你真正要说的是“扔掉我到目前为止所做的所有工作,除了第3和第4位置的部分”。

这段代码(未经测试)可能会解决您的问题:

代码语言:javascript
复制
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;

如果output[i+x]确实只在0、3范围内保存值,那么您可以如下所示修改代码:

代码语言:javascript
复制
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;

当然,如果你真的,真的很确定的话,这些断言可以被移除。但是,您也可以将它们保留在其中,并让编译器使用NDEBUG标志(g++ -DNDEBUG mycode.cpp)删除它们。有关更多细节,请参见this question

票数 5
EN

Stack Overflow用户

发布于 2017-08-10 02:00:39

这是因为在用新位填充nibble之前,您要用一个掩码过滤它,如果有什么不同的话,它所做的与它应该做的相反。

代码语言:javascript
复制
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);
                   ^^^^ in here you preserve the bits
             you want to replace and zero out everything else

倒置这个面具会有效的:

代码语言:javascript
复制
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);

但是,由于nibble已经以0的形式启动,所以您不需要这样做。就像在Richard's answer中那样填充比特即可。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45603191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档