使用6位设置浮动的分数部分

时间:2012-01-30 21:32:27

标签: c++ bit-manipulation bit

我正在从双字中解压缩一些数据。

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

4 个答案:

答案 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种移位指令:

  1. 右移带符号扩展:在将所有位向右移位后,它会将当前最左边的位作为新位复制到最左边。最右边的一个会掉线。
  2. 向右移动,零延伸:与(1)相同,但假设您的最左边的位始终为零。
  3. 左移:在中替换并再次阅读(2)。
  4. 向右滚动:向右移动你的位,而不是最右边的一个掉落,它就成了你最左边的。
  5. 向左滚动:将(em)中的替换为并读取(4) )再次。
  6. 您可以根据需要移动多次。在C中,未定义数据类型中的位数以上。虽然语法相同,但无符号和有符号类型的移位方式不同。

答案 3 :(得分:0)

如果您正在将数据作为unsigned char *读取,那么在数据时您将无法获得超过8位的数据,并且您的示例需要更改。如果您的地址是对齐的,或者您的平台允许,您应该以int *的形式读取数据,但这也会引发数据存储方式的问题。它是每个整数存储20位还是12位其他信息,还是20位流,您需要跟踪位指针。如果是第二个,它比你意识到的要复杂得多。一旦我了解了数据如何在RAM中布局,我就会进一步发布。