我正在做一个家庭作业,我们应该创建一个名为isGreater(x,y)的函数,如果x大于y则返回,但我们只能使用按位运算符和+和!。我已经解决了这个问题,如果x和y有不同的符号,那么使用规则,然后x> = 0,y< 0或者如果x和y具有相同的符号,那么仅当y-x为负时。
然而,当我环顾四周其他人如何解决它时,我注意到以下方法无论出于何种原因都能正常工作。
y = ~y;
return !(((x&y) + ((x^y) >> 1)) >> 31);
我不能为我的生活理解为什么这有效,我认为这与x中的第一位没有设置在y或其他东西有关?
注意:如果x和y是整数,而不是unsigned int,显然这只是一个有效的解决方案。
答案 0 :(得分:5)
31表示我们只对标志感兴趣。
如果((x& y)+((x ^ y)>> 1))> 0然后x> 〜年。
x& ~y将产生一个数字,其中MSB将是第一位,其中x具有设置位并且y具有0.x ^ ~y将产生一个数字,其中未设置位将表示x和y不同的位。如果我们将它正确地移动一个,我们需要他们的总和变得积极。仅当x& y的第一个非零位(意味着设置x并且x和y不同的第一个位)与((x ^ y)>> 1)中的设置位相遇时才会发生这种情况(意思是第一个在一个中设置但在另一个中没有设置的位。
如果最高位在x中设置但未在y中设置,则也是在一个中设置的最高位但在另一个中没有设置 - 这意味着x大于y。
示例:
(shft is x^~y >> 1, res is shft + x&~y)
x: 000110
y: 001010
~y: 110101
x&~y:000100
x^~y:110011
shft:111001
res: 111101 -> negative
x: 000110
y: 000010
~y: 111101
x&~y:000100
x^~y:111011
shft:111101
res: 000001 -> positive
这就是为什么它不适用于未签名的BTW(没有迹象)。