C语言 用按位运算符替换“==”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4161656/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:01:11  来源:igfitidea点击:

Replacing "==" with bitwise operators

cbinarybit-manipulation

提问by not_l33t

Using only bitwise operators (|, &, ~, ^, >>, <<) and other basic operators like +, -, and !, is it possible to replace the "==" below?

仅使用按位运算符(|、&、~、^、>>、<<)和其他基本运算符(如 +、- 和 !),是否可以替换下面的“==”?

int equal(int x, int y) {
    return x == y;
}

采纳答案by sth

Two numbers are equal if there is no difference between them:

如果它们之间没有差异,则两个数字相等:

int equal(int x, int y){
   return !(x-y);
}

回答by Ignacio Vazquez-Abrams

Remember that an XORis the exactly same as NOT EQUALSand XNORis exactly the same as EQUALS. So, the following will give you exactly what you want:

请记住, anXOR与 完全相同NOT EQUALS并且与XNOR完全相同EQUALS。因此,以下内容将为您提供您想要的内容:

return !(x ^ y);

回答by Fabian Giesen

The C !operator is really just shorthand for != 0, so using it seems very close to cheating :)

C!运算符实际上只是 的简写!= 0,因此使用它似乎非常接近作弊 :)

Here's my take just using bitwise operations, assuming a 32-bit two's complement machine with arithmetic right shifts (technically, in C arithmetic right shifts are undefined, but every C compiler I've ever seen on a two's complement machine supports this correctly):

这是我仅使用按位运算的看法,假设 32 位二进制补码机具有算术右移(从技术上讲,在 C 中算术右移是未定义的,但我在二进制补码机上见过的每个 C 编译器都正确支持这一点):

int t = (x - y) | (y - x); // <0 iff x != y, 0 otherwise
t >>= 31; // -1 iff x != y, 0 otherwise
return 1 + t; // 0 iff x != y, 1 otherwise

That said, actual compilers don't have this problem. Real hardware actually has direct support for comparisons. The details depend on the architecture, but there's two basic models:

也就是说,实际的编译器没有这个问题。真正的硬件实际上直接支持比较。细节取决于架构,但有两个基本模型:

  1. Condition codes returned for arithmetic operations (e.g. x86 and ARM do this). In this case, there's usually a "compare" instruction which subtracts two values, doesn't write back to an integer register but sets the condition code/flags based on the result.
  2. More RISC-like platforms typically have direct "branch if equal" and "branch if less than" operands that do a comparison and branch based on the result. It's basically equivalent to the C code

    if (a == b) goto label;
    

    or

    if (a < b) goto label;
    

    all in one machine instruction.

  1. 为算术运算返回的条件代码(例如 x86 和 ARM 执行此操作)。在这种情况下,通常有一个“比较”指令,它减去两个值,不会写回整数寄存器,而是根据结果设置条件代码/标志。
  2. 更多类似 RISC 的平台通常具有直接的“如果相等则分支”和“如果小于则分支”的操作数,它们根据结果进行比较和分支。它基本上等同于 C 代码

    if (a == b) goto label;
    

    或者

    if (a < b) goto label;
    

    全部在一个机器指令中。

回答by indiv

This example is the same as subtraction, but is more explicit as to how some architectures do register comparison (like the ARM, I believe).

这个例子与减法相同,但更明确地说明了一些架构如何进行寄存器比较(我相信像 ARM)。

return !(1 + ~x + y);

The 1 signifies the carry-bit input into the ALU. One number xis bitwise complemented. Taking the complement and adding 1 produces the two's complement of the number (xbecomes -x), and then it's added to the other number to get the difference to determine equality.

1 表示输入到 ALU 的进位位。一个数x按位求补。取补码并加 1 产生该数的二进制补码 ( xbecome -x),然后将其与另一个数相加得到差值以确定相等。

So if both numbers are equal, you get -x + x => 0.

所以如果两个数字相等,你就会得到-x + x => 0

(On a register level the !operator isn't done, and you just test the "zero bit" of the condition codes or flags register, which gets set if the register operation produces a result of zero, and is clear otherwise.)

(在寄存器级别,!运算符未完成,您只需测试条件代码或标志寄存器的“零位”,如果寄存器操作产生零结果,则设置该位,否则清除。)

回答by Saurabh Sachdeo

As XOR is same as (!=), hence (x ^ y) will return 0 only for equal values. My take is the following because it is sensible, uses bit-wise operator and working.

由于 XOR 与 (!=) 相同,因此 (x ^ y) 仅在值相等时返回 0。我的看法如下,因为它是明智的,使用按位运算符和工作。

int notEqual(int x, int y){
        return (x ^ y);
}

回答by Eternal Learner

My Take on this

我的看法

int equal(int x, int y){
   if((x & ~y) == 0)
       return 1;
   else
       return 0; 
}

Explanation: If x == y, then x & ~yevaluates to 0return 1, else return 0 as x!=y.

说明:如果x == y,则x & ~y计算0返回 1,否则返回 0 作为x!=y

Edit1: The above is equivalent to 

int equal(int x, int y){
    return !(x & ~y) ; // returns 1 if equal , 0 otherwise. 
}

The above code fails in certain cases where the Most significant bit turns to 1. The solution is to add a 1. i.e correct answer is

在某些情况下,最高有效位变为 1 时,上述代码会失败。解决方案是添加 1。即正确答案是

return !(x & (~y +1) );