给定一个 uint8_t 数组,将任何位子序列提取为 uint32_t 的好方法是什么?
我最近遇到了一个有趣的问题:
假设我有一个长度至少为 1 的字节数组(确切地说是 uint8_t)。现在我需要一个函数,该函数将从该数组中获取位的子序列,从位 X(基于零的索引,包括)开始,长度为 L,并将其作为 uint32_t 返回。如果 L 小于 32,则剩余的高位应为零。
虽然这并不是很难解决,但我目前关于如何做到这一点的想法对我来说似乎有点麻烦。我正在考虑一个给定字节的所有可能掩码的表(从位 0-7 开始,取 1-8 位),然后使用该表一次构造一个字节的数字。
有人能想出更好的解决方案吗?请注意,我不能为此使用 Boost 或 STL - 不,这不是作业,它是我在工作中遇到的问题,并且我们不会在该东西所在的代码中使用 Boost 或 STL。您可以假设: 0 < L <= 32 并且字节数组足够大以容纳子序列。
正确输入/输出的一个例子:
array: 00110011 1010 1010 11110011 01 101100
子序列:X = 12(从零开始的索引),L = 14
结果 uint32_t = 00000000 00000000 00 101011 11001101
I have run into an interesting problem lately:
Lets say I have an array of bytes (uint8_t to be exact) of length at least one. Now i need a function that will get a subsequence of bits from this array, starting with bit X (zero based index, inclusive) and having length L and will return this as an uint32_t. If L is smaller than 32 the remaining high bits should be zero.
Although this is not very hard to solve, my current thoughts on how to do this seem a bit cumbersome to me. I'm thinking of a table of all the possible masks for a given byte (start with bit 0-7, take 1-8 bits) and then construct the number one byte at a time using this table.
Can somebody come up with a nicer solution? Note that i cannot use Boost or STL for this - and no, it is not a homework, its a problem i run into at work and we do not use Boost or STL in the code where this thing goes. You can assume that: 0 < L <= 32 and that the byte array is large enough to hold the subsequence.
One example of correct input/output:
array: 00110011 1010 1010 11110011 01 101100
subsequence: X = 12 (zero based index), L = 14
resulting uint32_t = 00000000 00000000 00 101011 11001101
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
只有子序列中的第一个和最后一个字节将涉及一些位切片以获取所需的位,而中间字节可以整体移入结果中。这是一些示例代码,绝对未经测试 - 它执行我所描述的操作,但某些位索引可能会偏离一位:
Only the first and last bytes in the subsequence will involve some bit slicing to get the required bits out, while the intermediate bytes can be shifted in whole into the result. Here's some sample code, absolutely untested -- it does what I described, but some of the bit indices could be off by one:
看一下 std::bitset 和 boost::dynamic_bitset。
Take a look at std::bitset and boost::dynamic_bitset.
我会想到类似加载 uint64_t 并进行强制转换,然后左右移动以丢失无趣的位。
I would be thinking something like loading a uint64_t with a cast and then shifting left and right to lose the uninteresting bits.
为了完整起见,我添加了受此处评论和答案启发的解决方案。感谢所有愿意思考这个问题的人。
几点说明:我测试了代码,它似乎工作得很好,但是,可能存在错误。如果我找到任何,我会在这里更新代码。此外,可能还有更好的解决方案!
For the sake of completness, i'am adding my solution inspired by the comments and answers here. Thanks to all who bothered to think about the problem.
Few notes: i tested the code and it seems to work just fine, however, there may be bugs. If i find any, i will update the code here. Also, there are probably better solutions!