按位运算符

时间:2015-01-28 19:09:52

标签: c

我的这个功能有点麻烦。我们应该只使用位运算符(这意味着没有逻辑运算符,没有循环或if语句),我们不允许使用大于0xFF的常量。

我的功能正常工作,但它使用了一个巨大的常数。当我尝试使用较小的数字和移动来实现它时,我无法让它工作,我不知道为什么。

该函数应检查给定整数中的所有偶数位,如果它们都设置为1,则返回1.

工作代码

 int allEvenBits(int x) {
 /* implements a check for all even-numbered bits in the word set to 1 */
 /* if yes, the program outputs 1 WORKING */

 int all_even_bits = 0x55555555;
 return (!((x & all_even_bits) ^ all_even_bits)); 
 }

尝试使用较小的常量并移位

int allEvenBits(int x) {
/* implements a check for all even-numbered bits in the word set to 1 */
/* if yes, the program outputs 1 WORKING */

int a, b, c, d, e = 0;
int mask = 0x55;

/* first 8 bits */
a = (x & mask)&1;

/* second eight bits */
b = ((x>>8) & mask)&1;

/* third eight bits */
c = ((x>>16) & mask)&1;

/* fourth eight bits */
d = ((x>>24) & mask)&1;
e = a & b & c & d;
return e;
}

我在这里做错了什么?

5 个答案:

答案 0 :(得分:2)

我不知道你为什么要和你的价值观进行对比1.这是为了什么目的?

此代码未经测试,但我会按照以下方式执行操作。

int allEvenBits(int x) {
    return (x & 0x55 == 0x55) &&
        ((x >> 8) & 0x55 == 0x55) &&
        ((x >> 16) & 0x55 == 0x55) &&
        ((x >> 24) & 0x55 == 0x55);
} 

答案 1 :(得分:2)

例如,当你这样做时:

d = ((x>>24) & mask)&1;

..你实际上是在检查是否设置了最低位(值为1),而不是是否设置了任何掩码位......因为结尾处的&1是和的结果其余的1。如果您将&1更改为== mask,那么当1中设置的所有位都按照预期设置在mask时,您将获得(x>>24)。当然,其他类似的行也存在同样的问题。

如果您不能使用==!=之类的比较,那么您需要将所有有趣的位移到相同的位置,然后将它们组合在一起并使用遮罩消除其他位置。分两步,这可能是:

/* get bits that are set in every byte of x */
x = (x >> 24) & (x >> 16) & (x >> 8) & x;
/* 1 if all of bits 0, 2, 4 and 6 are set */
return (x >> 6) & (x >> 4) & (x >> 2) & x & 1;

答案 2 :(得分:1)

假设您正在检查前4个最低有效数字,偶数数字将1010。现在你应该将这与你要检查的数字的前4位进行对比。所有的1都应该留在那里。因此,对于4个最低有效位,测试将为((number & mask) == mask)(掩码为1010),您可以在4位块中执行此操作(或者您可以在允许的情况下使用8)。

答案 3 :(得分:1)

如果您不允许使用大于0xff的常量并且您的现有程序有效,那么如何更换:

int all_even_bits = 0x55555555;

由:

int all_even_bits = 0x55;
all_even_bits |= all_even_bits << 8;  /* it's now 0x5555 */
all_even_bits |= all_even_bits << 16; /* it's now 0x55555555 */

这里的一些其他答案右移有符号整数(即int),这是未定义的行为。

另一种途径是:

int allevenbitsone(unsigned int a)
{
    a &= a>>16; /* superimpose top 16 bits on bottom */ 
    a &= a>>8;  /* superimpose top 8 bits on bottom */
    a &= a>>4;  /* superimpose top 4 bits on bottom */
    a &= a>>2;  /* and down to last 2 bits */
    return a&1; /* return & of even bits */
}

这样做是将偶数16位加到第0位,将奇数16位加到第1位,然后返回第0位。

答案 4 :(得分:0)

你的代码中你要做的主要问题&1;所以你从数字中取出前8位,用0x55掩盖它们并且它们只使用第1位,这是错误的

考虑直截了当的方法:

int evenBitsIn8BitNumber(int a) {
    return (a & (a>>2) & (a>>4) & (a>>6)) & 1;
}

int allEvenBits(int a) {
    return evenBitsIn8BitNumber(a) &
        evenBitsIn8BitNumber(a>>8) &
        evenBitsIn8BitNumber(a>>16) &
        evenBitsIn8BitNumber(a>>24);
}