使用 6 位设置浮点数的小数部分
我正在从双字中解压缩一些数据。
unsigned char * current_word = [address of most significant byte]
我的前 14 个 MSB 是一个 int 值。我计划使用 0xFFFC 按位与来提取它们。
int value = (int)( (uint_16)current_word & 0xFFFC );
接下来的 6 位是小数值。在这里我陷入了有效的实施。我可以一次提取一位,并构建分数 1/2*bit + 1/4+bit + 1/8*bit 等...但这效率不高。
float fractional = ?
最后 12 个 LSB 是另一个 int 值,我觉得我可以再次使用按位 AND 来取出它。
int other_value = (int) ( (uint_16)current_word[2] & 0x0FFF );
该操作将在 16348 个双字上完成,并且需要在 0.05 ms 内完成才能至少运行 20Hz。
我对位操作很陌生,但我很高兴学习。阅读材料和/或示例将不胜感激!
编辑:当我的意思是“AND”时,我写了“OR”
I am uncompressing some data from double words.
unsigned char * current_word = [address of most significant byte]
My first 14 MSB are an int value. I plan to extract them using a bitwise AND with 0xFFFC.
int value = (int)( (uint_16)current_word & 0xFFFC );
My next 6 bits are a fractional value. Here I am stuck on an efficient implementation. I could extract one bit at a time, and build the fraction 1/2*bit + 1/4+bit + 1/8*bit etc ... but that's not efficient.
float fractional = ?
The last 12 LSB are another int value, which I feel I can pull out using bitwise AND again.
int other_value = (int) ( (uint_16)current_word[2] & 0x0FFF );
This operation will be done on 16348 double words and needs to be finished within 0.05 ms to run at least 20Hz.
I am very new to bit operations, but I'm excited to learn. Reading material and/or examples would be greatly appreciated!
Edit: I wrote OR when I meant AND
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
由于您从
[最高有效字节的地址]
开始并使用从那里开始递增的地址,因此您的数据显然采用 Big-Endian 字节顺序。因此,在几乎所有使用 Little-Endian 字节顺序的台式机上,指针转换都会失败。无论本机字节顺序如何,以下代码都将起作用:
Since you're starting with
[address of most significant byte]
and using increasing addresses from there, your data is apparently in Big-Endian byte order. Casting pointers will therefore fail on nearly all desktop machines, which use Little-Endian byte order.The following code will work, regardless of native byte order:
首先,您可以更有效地将双字一次性全部放入
int
中,并从那里进行掩码/移位。从中获取小数部分很容易:掩码和移位以获得整数,然后除以浮点数以缩放结果。
Firstly you'd be more efficient getting the double-word all at once into an
int
and masking/shifting from there.Getting the fractional part from that is easy: mask and shift to get an integer, then divide by a float to scale the result.
移位指令有 5 种:
您可以根据需要多次移动。在 C 中,数据类型中未定义的位数不止是位数。尽管语法相同,但无符号和有符号类型的转换方式不同。
there are 5 kinds of shift instructions:
You can shift as many times you want. In C, more than the amount of bits in your datatype is undefined. Unsigned and signed types shift differently although the syntax is same.
如果您将数据读取为 unsigned char *,则一次无法获取超过 8 位的数据,并且您的示例需要更改。如果您的地址是对齐的,或者您的平台允许,您应该以 int * 的形式读取数据,但这也引出了数据如何存储的问题。它是每个整数存储 20 位以及 12 位其他信息,还是需要跟踪位指针的 20 位流。如果是第二种,它比你想象的还要复杂。一旦我了解了您的数据在 RAM 中的布局方式,我将进一步发布。
If you are reading your data as unsigned char *, you are not going to be able to get more than 8-bits at a time of data and your example needs to change. If your address is aligned, or your platform allows, you should read your data in as an int *, but then that also begs the question of just how your data is stored. Is it stored 20-bits per integer with 12-bits of other info, or is it a 20-bit stream where you need to keep track of your bit pointer. If the second, it's even more complex than you realize. I'll post further once I have a feel for how your data is laid out in RAM.