有没有一种快速的方法来按索引(而不仅仅是屏蔽)提取位?

Is there a fast method to extract bits by index (not just masking)?

提问人:António Leitão 提问时间:3/10/2023 最后编辑:cafce25António Leitão 更新时间:3/15/2023 访问量:76

问:

我有一个特定的二进制数,例如:11110000 以及正好设置了 4 位的掩码:10101010 我正在寻找一个快速操作,该操作将返回与设置掩码的位置相对应的 4 位输入:

11110000 10101010 产量:1100

在这里,我使用 u8 到 u4,但想象一下 u64 到 u32。有没有一种快速的方法可以在不循环的情况下做到这一点(在 Rust 或 C 中)?

我尝试循环索引和线性分解。两者都非常慢,因为一个需要循环,另一个需要矩阵分解。

与语言无关的 位掩码

评论

1赞 kiner_shah 3/10/2023
不要发送垃圾标签。如果你想要 Rust 或 C,请删除 C++ 和 Javascript 标签。
0赞 0___________ 3/10/2023
我不知道什么是“正好设置了 4 位的掩码”以及与预期输出的关系。我看不出它们之间有任何关系
2赞 Jonas Fassbender 3/10/2023
当你的掩码是已知的,你不能将你的掩码分成 4 个掩码,每个掩码有一个位,然后将每个掩码的结果转移到你想在输出中存储它的位吗?这就是我对你的具体例子的意思。我认为这将是一个相当快的操作
1赞 António Leitão 3/10/2023
@JonasFassbender,是的,这是一个好主意(这相当于线性分解,其基础是 4 个不同的向量),它运行良好,但对于 u32 及更高版本的扩展性很差。我想知道是否有更快的方法
1赞 Masklinn 3/10/2023
@JonasFassbender FWIW Godbolt 支持 Rust,并且比此类演示的游乐场更好/更方便,这是您的片段

答:

0赞 Matt Timmermans 3/15/2023 #1

如果可以预处理选择掩码,则可以在掩码和移位操作的 log(width) 数中执行此操作。

如果您的选择蒙版中有任何奇数大小的间隙,那么您可以首先应用位蒙版向右移动一个位置,结果您想要的位之间只会有偶数大小的间隙。

例如,从 的选择掩码 开始,向右移动 1 位的位是 。移动这些位后,要应用的新选择蒙版是 ,它只有偶数大小的间隙。101010100010001010011001

然后有一个蒙版,用于向右移动 2 个位置,这将使您的所有间隙大小可以被 4 整除:10011001 -> 10000111

如果继续这样,直到间隙大小可以被字长整除,那么就不会有任何间隙:10000111 -> 00001111

要计算这些掩码,首先计算每个位位置所需的总位移。第一个掩码从所有奇数总位移中清除 1 位。第二个掩码清除 2 位,依此类推。