替换“==”与按位运算符

发布于 2024-10-02 13:50:38 字数 150 浏览 3 评论 0原文

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

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

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

流殇 2024-10-09 13:50:38

请记住,XORNOT EQUALS 完全相同,XNOREQUALS 完全相同。因此,以下内容将为您提供您想要的:

return !(x ^ y);

Remember that an XOR is the exactly same as NOT EQUALS and XNOR is exactly the same as EQUALS. So, the following will give you exactly what you want:

return !(x ^ y);
无敌元气妹 2024-10-09 13:50:38

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

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

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

int equal(int x, int y){
   return !(x-y);
}
不知在何时 2024-10-09 13:50:38

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

这是我仅使用按位运算的看法,假设是 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

也就是说,实际的编译器不存在此问题。真实的硬件实际上可以直接支持比较。详细信息取决于体系结构,但有两种基本模型:

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

    if (a == b) 转到标签;
    

    if (a < b) 转到标签;
    

    全在一个机器指令中。

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

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):

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.

落花随流水 2024-10-09 13:50:38

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

return !(1 + ~x + y);

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

因此,如果两个数字相等,您将得到 -x + x => 0 。

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

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

return !(1 + ~x + y);

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

So if both numbers are equal, you get -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.)

心碎无痕… 2024-10-09 13:50:38

由于 XOR 与 (!=) 相同,因此 (x ^ y) 仅当值相等时才会返回 0。
我的看法如下,因为它是明智的,使用按位运算符并且有效。

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

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.

int notEqual(int x, int y){
        return (x ^ y);
}
仅冇旳回忆 2024-10-09 13:50:38

我对此

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

解释的看法:如果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. 
}

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

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

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 & ~y evaluates to 0 return 1, else return 0 as 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

return !(x & (~y +1) );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文