我正在从双字中解压缩一些数据。
unsigned char * current_word = [address of most significant byte]
我的前14个MSB是一个int值。我计划使用按位AND和0xFFFC来提取它们。
int value = (int)( (uint_16)current_word & 0xFFFC );
我接下来的6位是小数值。在这里,我坚持有效的实施。我可以一次提取一个比特,并构建分数1/2 *比特+ 1/4 +比特+ 1/8 *比特等......但这效率不高。
float fractional = ?
最后12个LSB是另一个int值,我觉得我可以再次使用按位AND。
int other_value = (int) ( (uint_16)current_word[2] & 0x0FFF );
此操作将在16348个双字上完成,需要在0.05 ms内完成,至少运行20Hz。
我对位操作很新,但我很高兴学习。阅读材料和/或示例将不胜感激!
编辑:当我的意思是和
时,我写了OR答案 0 :(得分:2)
首先,您可以更高效地将双字一次性地转换为int
并从那里进行屏蔽/转换。
从中获取小数部分很容易:使用掩码和移位来获取整数,然后除以浮点数来缩放结果。
float fractional = ((current_int >> 12) & 0x3f) / 64.;
答案 1 :(得分:2)
由于您从 [address of most significant byte]
开始并使用增加的地址,因此您的数据显然是以Big-Endian字节顺序排列的。因此,几乎所有使用Little-Endian字节顺序的桌面计算机上的转换指针都会失败。
以下代码将起作用,无论本机字节顺序如何:
int value = (current_word[0] << 6) | (current_word[1] >> 2);
double fractional = (current_word[1] & 0x03) / 4.0 + (current_word[2] & 0xF0) / 1024.0;
int other_value = (current_word[2] & 0x0F) << 8 | current_word[3];
答案 2 :(得分:0)
有5种移位指令:
您可以根据需要移动多次。在C中,未定义数据类型中的位数以上。虽然语法相同,但无符号和有符号类型的移位方式不同。
答案 3 :(得分:0)
如果您正在将数据作为unsigned char *读取,那么在数据时您将无法获得超过8位的数据,并且您的示例需要更改。如果您的地址是对齐的,或者您的平台允许,您应该以int *的形式读取数据,但这也会引发数据存储方式的问题。它是每个整数存储20位还是12位其他信息,还是20位流,您需要跟踪位指针。如果是第二个,它比你意识到的要复杂得多。一旦我了解了数据如何在RAM中布局,我就会进一步发布。