seb*_*ebi 12 c bit-manipulation bitmask
有人可以向我解释这个功能吗?
具有最低有效n位的掩码设置为1.
例如:
n = 6 - > 0x2F,n = 17 - > 0x1FFFF //我根本得不到这些,尤其是n = 6 - > 0x2F
还有什么是面具?
Jer*_*fin 25
通常的方法是取一个1
,然后将它移位n
.这会给你一些类似的东西:00100000
.然后从中减去一个,这将清除所设置的位,并设置所有不太重要的位,所以在这种情况下我们得到:00011111
.
掩码通常用于按位操作,尤其是and
.您可以使用上面的掩码自行获取5个最低有效位,与可能存在的任何其他位置隔离.这在处理通常具有单个硬件寄存器的硬件时尤其常见,该硬件寄存器包含表示多个完全独立的,无关的量和/或标志的位.
掩码是整数值的常用术语,该整数值与另一个整数值进行逐位AND运算,OR运算,XOR运算等.
例如,如果要提取int变量的8个最低有效数字,则可以variable & 0xFF
.0xFF是一个掩码.
同样,如果你想设置位0和8,你可以这样做variable | 0x101
,其中0x101是一个掩码.
或者,如果要反转相同的位,则执行此操作variable ^ 0x101
,其中0x101是掩码.
要为你的情况生成一个掩码,你应该利用一个简单的数学事实:如果你在掩码中添加1(掩码的所有最低有效位设置为1,其余的为0),你得到的值就是2.
因此,如果您生成最接近2的幂,则可以从中减去1以获得掩码.
使用<<
C中的左移位运算符可以轻松生成2的正幂.
因此,1 << n
产量2 n.在二进制中,它是10 ... 0和n
0.
(1 << n) - 1
将生成一个n
最低位设置为1 的掩码.
现在,您需要注意左移的溢出.在C(和C++中)中,你不能合法地将变量左移由与变量一样多的位位置,因此如果整数是32位,则1<<32
导致undefined behavior
.还应避免使用有符号整数溢出,因此应使用无符号值,例如1u << 31
.
小智 8
对于正确性和性能,实现这一目标的最佳方法已经改变,因为在2012年由于现代x86处理器(特别是BLSMSK)中BMI指令的出现而回答了这个问题.
这是解决此问题的好方法,同时保留与旧处理器的向后兼容性.
此方法是正确的,而当前的顶部答案在边缘情况下产生未定义的行为.
当允许使用BMI指令进行优化时,Clang和GCC会将gen_mask()压缩为两个操作.使用支持硬件,请务必为BMI指令添加编译器标志:
-mbmi -mbmi2
#include <inttypes.h>
#include <stdio.h>
uint64_t gen_mask(const uint_fast8_t msb) {
const uint64_t src = (uint64_t)1 << msb;
return (src - 1) ^ src;
}
int main() {
uint_fast8_t msb;
for (msb = 0; msb < 64; ++msb) {
printf("%016" PRIx64 "\n", gen_mask(msb));
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
27410 次 |
最近记录: |