使用 6 位设置浮点数的小数部分
Set A Float's Fractional Part Using 6 Bits
我正在从双字中解压缩一些数据。
unsigned char * current_word = [address of most significant byte]
我的前14个MSB是一个int值。我计划使用0xFFFC的逐位AND来提取它们。
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.05ms内完成才能运行至少20Hz。
我对钻头操作很陌生,但我很兴奋能学习。阅读材料和/或示例将不胜感激!
编辑:当我指的是AND 时,我写了OR
由于您从[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];
首先,将双字同时放入int
并从中屏蔽/移位会更有效。
从中得到分数部分很容易:掩码和移位得到一个整数,然后除以浮点值来缩放结果。
float fractional = ((current_int >> 12) & 0x3f) / 64.;
有5种移位指令:
- 符号扩展右移:在将所有位右移后,它会将当前最左边的位复制为最左边的新位。最右边的一个掉了
- 使用零扩展右移:与(1)相同,但假设新的最左边的位始终为零
- 向左移位:将(1)和(2)中的right替换为left,将left更改为right并再次读取(2)
- 向右滚动:将你的比特向右移动,而不是最右边的一个,它变成了你的最左边
- 向左滚动:用左替换(4)中的右,用右替换左并再次读取(4)
你可以随心所欲地变换。在C中,超过数据类型中的位数是未定义的。尽管语法相同,但无符号类型和有符号类型的偏移不同。
如果您将数据读取为无符号char*,则一次无法获得超过8位的数据,因此您的示例需要更改。如果你的地址是对齐的,或者你的平台允许,你应该以int*的形式读取数据,但这也引出了如何存储数据的问题。它是每个整数存储20位,还有12位其他信息,还是一个需要跟踪位指针的20位流。如果是第二个,它甚至比你意识到的更复杂。一旦我对你的数据在RAM中的布局有了感觉,我会进一步发布。
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 使用提升将数据从 PyObject 复制到浮点数 *
- 使用浮点数和双精度数的非常小数字的数学
- 使用英特尔内联函数将打包的 8 位整数乘以浮点数向量
- 如何在 c++ 中将小数点后两位数的浮点数分配给另一个浮点数
- 返回浮点数的小数位数
- txt 文件中浮点数的最大和最小值
- 为什么 std::cout 打印浮点数、双精度和长双精度到相同的小数精度?
- 在数学上将浮点数四舍五入到 N 位小数
- 从浮点数中删除小数部分但保留类型的有效方法
- 小数浮点数缺少除法 (C++)
- 如何计算C++浮点数中的小数位数
- 将浮点数四舍五入为2位小数,将其写入文本文件
- 使用 6 位设置浮点数的小数部分
- 将浮点数截断为前导N位小数
- 精确地提取浮点数的小数部分
- 将浮点数打印为小数并修复错误输出
- 如何计算具有 n 位小数的浮点数