有人能请解释一下这个功能对我?
用最少的显著n比特的掩模设置为1。
例如:
N = 6 - >值为0x2F,N = 17 - > 0x1FFFF //我不明白这些可言,尤其是如何N = 6 - >值为0x2F
此外,什么是面膜?
有人能请解释一下这个功能对我?
用最少的显著n比特的掩模设置为1。
例如:
N = 6 - >值为0x2F,N = 17 - > 0x1FFFF //我不明白这些可言,尤其是如何N = 6 - >值为0x2F
此外,什么是面膜?
通常的方法是采用一个1
,移位它留下n
位。 这会给你是这样的: 00100000
。 然后减去一个从,这将清除我们设置位,并设置所有的少显著位,所以在这种情况下,我们会得到: 00011111
。
掩模通常为位操作使用,特别是and
。 你会使用上面的面具由自己来获得至少5位显著,从其他任何可能存在的孤立。 与将通常具有包含表示多个完全独立的,不相关的数量和/或标志的比特的单个硬件寄存器硬件处理时,这是尤其普遍的。
掩模是一个整数值,是逐位AND运算,或运算,异或等与另一整数值的普通术语。
例如,如果要提取一个int变量的8个最低显著数字,你做的variable & 0xFF
。 0xFF的是荫罩。
同样,如果你想设置位0和8,你做variable | 0x101
variable | 0x101
,其中0x101是掩模。
或者,如果要反转同位,你做variable ^ 0x101
,在0x101是一个面具。
要生成你的情况,你应该利用这个简单的数学事实,如果你加1到你的掩模(其设置为1,其所有至少显著位,其余为0,掩码)一个面具,你会得到一个值,该值的功率2。
所以,如果你生成的2最接近的力量,那么你可以从它减去1得到面具。
的2正幂容易与左移产生<<
操作者C.
因此, 1 << n
产量2 n个 。 在二进制是10 ... 0与n
0。
(1 << n) - 1
将产生的掩模n
设置为1最低位。
现在,你需要提防左移溢出。 在C(和在C ++)你不能合法移位由多达位位置留下了变量作为变量,因此,如果整数是32位, 1<<32
导致undefined behavior
。 有符号整数溢出也应避免,所以你应该使用无符号的值,例如1u << 31
。
对于正确性和性能,做到这一点的最好办法已经由于BMI说明在现代x86处理器的出现,特别是BLSMSK改变,因为这个问题被要求回到2012年。
下面是处理这个问题的好办法,同时保持向后兼容旧的处理器的兼容性。
这种方法是正确的,而目前最顶级的答案产生边缘情况不确定的行为。
铛和GCC,允许使用BMI指令优化时,就会凝结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;
}
我相信,你的第一个例子应该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;
}
0x2F
是0010 1111
以二进制-这应当0x3f
,这是0011 1111
在二进制和具有设置6至少-显著位。
类似地, 0x1FFFF
是0001 1111 1111 1111 1111
在二进制的,其具有设置17至少-显著位。
A“掩模”是旨在与另一值进行组合使用按位操作者的值等&
, |
或^
单独设置,取消设置,翻转或保持不变的在其他时间的位元。
例如,如果你把面具0x2F
一些价值n
使用&
操作,结果将在所有零,但至少6位显著,和那些6位将被复制从值不变n
。
在一个的情况下&
掩模,二进制0
的屏蔽装置“无条件设定结果位为0”和1
表示“设置的结果位的输入值的位”。 对于|
掩模,一个0
掩模中的结果位设置到输入位和1
无条件地将结果位到1
,和用于^
掩模,一个0
设定结果位于输入位和1
套的结果位输入位的补码。
首先,对于那些谁只想代码来创建蒙版:
uint64_t bits = 6;
uint64_t mask = ((uint64_t)1 << bits) - 1;
# Results in 0b111111 (or 0x03F)
对于那些谁想要知道面具是什么:
掩码通常是值的名称,我们用它来操作使用逐操作,如AND,OR,XOR等其他值
短面罩通常在二进制,在这里我们可以明确地看到,被设置为1的所有位代表。
更长的面具通常以十六进制表示,那是很容易的,一旦你得到了它保持阅读。
你可以阅读更多关于用C位运算这里去你得到的材料更好地把握。