这是一项家庭作业,要求我提出一个函数来确定x < y
,如果是,我必须只使用按位运算符1
返回( ! ~ & ^ | + << >> )
。我只允许使用常量0 - 0xFF
,并假设一个32位整数。没有循环,铸造等等。
我想到的是,如果你只检查说4位,你可以x - y
确定x
是否小于y
。如果x
为8
且y
为9
,1111
的结果为-1
。
int lessThan(int x, int y){
int sub = x + (~y+1);
我感到困惑的是如何将该结果与x
进行比较,以确定它确实小于y
。
我一直在研究这篇文章here。
但我对这个问题的方法感到有点困惑。我已经计算出变换以获得位模糊,但我对如何使用该结果来比较小于或大于的值感到困惑。我只是在寻找一些指导和清晰度,而不是解决方案,这不是我的意图。
答案 0 :(得分:1)
实施减法的想法很好。
int sub = x + (~y+1);
从这里开始,您只需检查sub
是否为负数,即提取其符号位。这就是出现技术难题的地方。
假设x
和y
是无符号的32位整数。然后减法的结果可以用带符号的33位整数表示(检查其最小值和最大值以查看)。也就是说,直接使用表达式x + (~y+1)
没有帮助,因为它会溢出。
如果x
和y
是31位无符号数,该怎么办?然后,x + (~y+1)
可以用32位有符号数表示,其符号位告诉我们x
是否小于y
:
answer(x, y) := ((x + (~y+1)) >> 31) & 1
要将x
和y
从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)
我认为可以做到以下几点:
代码:
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