如何创建与面膜至少significat位用设定为1(How to create mask with

2019-07-31 14:20发布

有人能请解释一下这个功能对我?

用最少的显著n比特的掩模设置为1。

例如:

N = 6 - >值为0x2F,N = 17 - > 0x1FFFF //我不明白这些可言,尤其是如何N = 6 - >值为0x2F

此外,什么是面膜?

Answer 1:

通常的方法是采用一个1 ,移位它留下n位。 这会给你是这样的: 00100000 。 然后减去一个从,这将清除我们设置位,并设置所有的少显著位,所以在这种情况下,我们会得到: 00011111

掩模通常为位操作使用,特别是and 。 你会使用上面的面具由​​自己来获得至少5位显著,从其他任何可能存在的孤立。 与将通常具有包含表示多个完全独立的,不相关的数量和/或标志的比特的单个硬件寄存器硬件处理时,这是尤其普遍的。



Answer 2:

掩模是一个整数值,是逐位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



Answer 3:

对于正确性和性能,做到这一点的最好办法已经由于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;
}


Answer 4:

我相信,你的第一个例子应该0x3f

0x3f是数十六进制表示法63111111以二进制,使得最后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;
}


Answer 5:

0x2F0010 1111以二进制-这应当0x3f ,这是0011 1111在二进制和具有设置6至少-显著位。

类似地, 0x1FFFF0001 1111 1111 1111 1111在二进制的,其具有设置17至少-显著位。

A“掩模”是旨在与另一值进行组合使用按位操作者的值等&|^单独设置,取消设置,翻转或保持不变的在其他时间的位元。

例如,如果你把面具0x2F一些价值n使用&操作,结果将在所有零,但至少6位显著,和那些6位将被复制从值不变n

在一个的情况下&掩模,二进制0的屏蔽装置“无条件设定结果位为0”和1表示“设置的结果位的输入值的位”。 对于| 掩模,一个0掩模中的结果位设置到输入位和1无条件地将结果位到1 ,和用于^掩模,一个0设定结果位于输入位和1套的结果位输入位的补码。



Answer 6:

首先,对于那些谁只想代码来创建蒙版:

uint64_t bits = 6;
uint64_t mask = ((uint64_t)1 << bits) - 1;
# Results in 0b111111 (or 0x03F)

对于那些谁想要知道面具是什么:

掩码通常是值的名称,我们用它来操作使用逐操作,如AND,OR,XOR等其他值

短面罩通常在二进制,在这里我们可以明确地看到,被设置为1的所有位代表。

更长的面具通常以十六进制表示,那是很容易的,一旦你得到了它保持阅读。

你可以阅读更多关于用C位运算这里去你得到的材料更好地把握。



文章来源: How to create mask with least significat bits set to 1 in C