用于查找小于c的按位运算符

时间:2013-01-29 17:01:57

标签: c bitwise-operators

这是一项家庭作业,要求我提出一个函数来确定x < y,如果是,我必须只使用按位运算符1返回( ! ~ & ^ | + << >> )。我只允许使用常量0 - 0xFF,并假设一个32位整数。没有循环,铸造等等。

我想到的是,如果你只检查说4位,你可以x - y确定x是否小于y。如果x8y91111的结果为-1

int lessThan(int x, int y){
    int sub = x + (~y+1); 

我感到困惑的是如何将该结果与x进行比较,以确定它确实小于y

我一直在研究这篇文章here

但我对这个问题的方法感到有点困惑。我已经计算出变换以获得位模糊,但我对如何使用该结果来比较小于或大于的值感到困惑。我只是在寻找一些指导和清晰度,而不是解决方案,这不是我的意图。

4 个答案:

答案 0 :(得分:1)

实施减法的想法很好。

int sub = x + (~y+1);

从这里开始,您只需检查sub是否为负数,即提取其符号位。这就是出现技术难题的地方。

假设xy是无符号的32位整数。然后减法的结果可以用带符号的33位整数表示(检查其最小值和最大值以查看)。也就是说,直接使用表达式x + (~y+1)没有帮助,因为它会溢出。

如果xy是31位无符号数,该怎么办?然后,x + (~y+1)可以用32位有符号数表示,其符号位告诉我们x是否小于y

answer(x, y) := ((x + (~y+1)) >> 31) & 1

要将xy从32位转换为31位,将它们的MSB(最高有效位)和所有其他31位分成不同的变量:

msb_x = (x >> 31) & 1;
msb_y = (y >> 31) & 1;
x_without_msb = x << 1 >> 1;
y_without_msb = y << 1 >> 1;

然后考虑他们的MSB的4种可能组合:

if (msb_x == 0 && msb_y == 0)
    return answer(x_without_msb, y_without_msb);
else if (msb_x == 1 && msb_y == 0)
    return 0; // x is greater than y
else if (msb_x == 0 && msb_y == 1)
    return 1; // x is smaller than y
else
    return answer(x_without_msb, y_without_msb);

将所有这些if语句转换为单个丑陋的逻辑表达式是“读者的练习”。

答案 1 :(得分:0)

这是我的尝试(编译结果,x&gt; y然后0,x&lt; y然后1,x == y然后1):

((((x + ~y) >> 31) + 1))^1

答案 2 :(得分:0)

我认为可以做到以下几点:

  1. Xor这两个数字,这将给你不同的位
  2. 获得最重要的一点,因为这个会有所不同
  3. 检查最重要的位是否属于更大的值
  4. 代码:

    int less(int x, int y) {
        //Get only diffed bits
        int msb = x ^ y;
        //Get first msb bit
        msb |= (msb >>  1);
        msb |= (msb >>  2);
        msb |= (msb >>  4);
        msb |= (msb >>  8);
        msb |= (msb >> 16);
        msb = msb - (msb >> 1);
        //check if msb belongs to y;
        return !((y & msb) ^ msb);
    }
    

答案 3 :(得分:-1)

为了了解x < y,您可以简单地询问x - y < 0

换句话说,x - y的结果是什么。

由于您声明要假设32位整数,以下将提供正确的结果:

((x - y) >> 31) & 0x1