2015-02-08 81 views
7

使用按位运算符如何测试整数的n个最低有效位是全集还是全集。如何测试所有位是否置1或所有位不是?

例如if n = 3我只关心3至少显著位的测试应该在0和7和假返回true 0和7

当然,我可以做if x = 0 or x = 7之间的所有其他值,但我会更喜欢使用按位运算符的东西。

如果该技术可以适用于考虑由掩码定义的所有位,则可获得奖励点数。

澄清:

如果我想如果位一个或两个设为我所能if ((x & 1 != 0) && (x & 2 != 0))测试。但我可以做“更高效”if ((x & 3) != 0)

我试图找到一个像这样的“黑客”来回答这个问题:“匹配这个掩码的所有位都是全部设置还是全部未设置?”

简单的方法是if ((x & mask) == 0 || (x & mask) == mask)。我想找到一种方法在没有||的单个测试中执行此操作运营商。

+0

什么是用例?为什么你想要这样的方法 – 2015-02-08 04:48:35

+0

我有兴趣在位操纵黑客通过阅读这里https://graphics.stanford.edu/~seander/bithacks.html我试图找到一种方法来测试,如果所有位的蒙面人要么全是1人,要么全是0.这只是好奇心,我不知道是否可以做到。 – 2015-02-08 04:52:28

+0

有几个答案会导致编写'1 << n'的错误。这会导致未定义的行为,如果n> = 31(如果你在32位int系统中)。 '1'需要被转换为无符号类型,至少与您正在测试的值一样宽。 – 2015-02-08 21:29:07

回答

10

使用按位运算符如何测试整数的n个最低有效位是全集还是全集而非集。

要获得最后n显著位的面具,那

(1ULL << n) - 1 

所以简单的测试:

bool test_all_or_none(uint64_t val, uint64_t n) 
{ 
    uint64_t mask = (1ULL << n) - 1; 
    val &= mask; 
    return val == mask || val == 0; 
} 

如果你想避免||,我们将有利用整数溢出。对于我们想要的情况,在&,val之后是0或者(假设n == 8)0xff。因此val - 10xffffffffffffffff0xfe。失败原因是10xfe,它们变成00xfd。因此,成功的案例是调用至少0xfe,这是mask - 1

bool test_all_or_none(uint64_t val, uint64_t n) 
{ 
    uint64_t mask = (1ULL << n) - 1; 
    val &= mask; 
    return (val - 1) >= (mask - 1); 
} 

我们还可以测试加1,而不是减1,这可能是最好的解决方法(在这里,一旦我们添加一个valval & mask应要么成为或01我们的成功案例):

bool test_all_or_none(uint64_t val, uint64_t n) 
{ 
    uint64_t mask = (1ULL << n) - 1; 
    return ((val + 1) & mask) <= 1; 
}  

对于任意面具,扣除法适用于同样的原因,它的工作的具体情况面膜:0翻转是最大的可能值:

bool test_all_or_none(uint64_t val, uint64_t mask) 
{ 
    return ((val & mask) - 1) >= (mask - 1); 
} 
+0

我不是在寻找一种方法来分别测试它们。我想同时测试两者。 – 2015-02-08 04:53:55

+0

@MathieuPagé想出了一个更好的。 – Barry 2015-02-08 05:00:48

+0

不错的一个。这回答我原来的问题,我想测试n个最低有效位。如果我们没有找到适用于任意掩码的版本,我会接受这个答案。谢谢。 – 2015-02-08 05:06:52

3

怎么样?

int mask = (1<<n)-1; 
if ((x&mask)==mask || (x&mask)==0) { /*do whatever*/ } 

唯一真正棘手的部分是掩码的计算。它基本上只是移动1来获得0b0...0100...0,然后减去1使其成为0b0...0011...1

也许你可以澄清你想要测试什么?

+0

我希望在不使用||的情况下进行测试运营商。 – 2015-02-08 04:55:19

+1

@MathieuPagé确实使用'|' – ryanpattison 2015-02-08 05:05:13

+0

@MattMcNabb;当我在第一学期记住时,第二学期被排除在外。固定。 – imallett 2015-02-08 22:11:06

0

为了测试是否所有的都没有设置,你只需要掩盖,只有在您需要的位,那么你只需要比较为零。

乐趣开始当您刚刚反相输入:)

//Test if the n least significant bits arent set: 
char n_least_arent_set(unsigned int n, unsigned int value){ 
    unsigned int mask = pow(2, n) - 1; // e. g. 2^3 - 1 = b111 
    int masked_value = value & mask; 
    return masked_value == 0; // if all are zero, the mask operation returns a full-zero.  
} 

//test if the n least significant bits are set: 
char n_least_are_set(unsigned int n, unsigned int value){ 
    unsigned int rev_value = ~value; 
    return n_least_arent_set(n, rev_value);  
} 
1

定义oposite功能这里是你想做的事,在一个函数什么(未经测试,但你应该明白我的意思)。如果没有设置n个最后位,则返回0;如果全部设置,则返回1;否则返回-1。

int lastBitsSet(int num, int n){ 
    int mask = (1 << n) - 1; //n 1-s 
    if (!(num & mask)) //we got all 0-s 
     return 0; 
    if (!(~num & mask)) //we got all 1-s 
     return 1; 
    else 
     return -1; 
} 
+0

嗨Mints97,我正在寻找一种方法在单个测试中做到这一点。 @Barry找到了一种方法来实现掩码覆盖最小有效位的情况。 – 2015-02-08 05:14:45

+0

@MathieuPagé:是的,但是他的方法并没有区分最后一些比特全部设置或全部未设置的情况。 – Mints97 2015-02-08 05:17:32

+0

确实。那正是我正在寻找的。 – 2015-02-08 05:25:39

相关问题