有人可以向我解释这个功能吗?
具有最低有效n位的掩码设置为1.
例如:
n = 6 - > 0x2F,n = 17 - > 0x1FFFF //我根本得不到这些,特别是n = 6 - >值为0x2F
另外,什么是面具?
答案 0 :(得分:24)
通常的方法是取1
,然后将其向左移n
位。这会给你类似的东西:00100000
。然后从中减去一个,这将清除设置的位,并设置所有不太重要的位,所以在这种情况下我们得到:00011111
。
掩码通常用于按位操作,尤其是and
。您可以使用上面的掩码自行获取5个最低有效位,与可能存在的任何其他位置隔离。这在处理硬件时尤为常见,这些硬件通常只有一个硬件寄存器,其中包含代表一些完全独立的无关数量和/或标志的位。
答案 1 :(得分:8)
对于正确性和性能,自2012年因为现代x86处
这是解决此问题的好方法,同时保留了与旧处理器的向后兼容性。
此方法是正确的,而当前的最高答案会在边缘情况下产生未定义的行为。
当允许使用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;
}
答案 2 :(得分:7)
掩码是整数值的常用术语,它与另一个整数值进行逐位AND运算,ORed运算,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
。
答案 3 :(得分:0)
我相信你的第一个例子应该是0x3f
。
0x3f
是数字63
的十六进制表示法,二进制为111111
,因此最后6位(最低有效6位)设置为1
。
以下小C程序将计算正确的掩码:
#include <stdarg.h>
#include <stdio.h>
int mask_for_n_bits(int n)
{
int mask = 0;
for (int i = 0; i < n; ++i)
mask |= 1 << i;
return mask;
}
int main (int argc, char const *argv[])
{
printf("6: 0x%x\n17: 0x%x\n", mask_for_n_bits(6), mask_for_n_bits(17));
return 0;
}
答案 4 :(得分:0)
0x2F
是二进制的0010 1111
- 这应该是0x3f
,二进制是0011 1111
,并且设置了6个最低有效位。
同样,0x1FFFF
为二进制0001 1111 1111 1111 1111
,其中设置了17个最低有效位。
“掩码”是一个值,旨在使用&
,|
或^
之类的按位运算符与其他值组合,以单独设置,取消设置,翻转或离开未改变其他值中的位。
例如,如果使用0x2F
运算符将掩码n
与某个值&
组合在一起,则除了6个最低有效位之外,结果中的所有值都为零,并且位将从值n
中保持不变。
在&
掩码的情况下,掩码中的二进制0
表示“无条件地将结果位设置为0”,而1
表示“将结果位设置为输入值位“。对于|
掩码,掩码中的0
将结果位设置为输入位,1
无条件地将结果位设置为1
,并^
为0
1}}掩码,1
将结果位设置为输入位,{{1}}将结果位设置为输入位的补码。
答案 5 :(得分:0)
首先,对于只希望代码创建掩码的用户:
uint64_t bits = 6;
uint64_t mask = ((uint64_t)1 << bits) - 1;
# Results in 0b111111 (or 0x03F)
对于那些想知道什么是面具的人:
掩码通常是值的名称,我们使用它使用AND,OR,XOR等按位运算来操纵其他值。
短掩码通常以二进制表示,我们可以在其中明确看到设置为1的所有位。
更长的掩码通常以十六进制表示,一旦掌握它,它真的很容易阅读。
您可以阅读有关C here中按位运算的更多信息,从而可以更好地掌握本文的内容。