C# XOR运算符-它是如何工作的?
请用简单的英语向我解释什么是XOR(C# XOR运算符-它是如何工作的?,c#,binary,bitwise-operators,xor,C#,Binary,Bitwise Operators,Xor,请用简单的英语向我解释什么是XOR(^)运算符,以及它在以下代码中的作用: public int GetHashCode(Box bx) { int hCode = bx.Height ^ bx.Length ^ bx.Width; return hCode.GetHashCode(); } XOR代表异或。它确保A或B为真,但决不能两者都为真。在本例中,我们正在执行一个逐位运算,这样您就可以生成一个漂亮的结果图,如下所示: 0 ^ 1 = 1 1 ^ 1 = 0 1 ^ 0
^
)运算符,以及它在以下代码中的作用:
public int GetHashCode(Box bx)
{
int hCode = bx.Height ^ bx.Length ^ bx.Width;
return hCode.GetHashCode();
}
XOR代表异或。它确保A或B为真,但决不能两者都为真。在本例中,我们正在执行一个逐位运算,这样您就可以生成一个漂亮的结果图,如下所示:
0 ^ 1 = 1
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 0 = 0
由于将其应用于整数,上述结果将应用于操作数中的每一位。所以我们假设高度、长度和宽度的值分别为1、2、3
你会先
0001^0010导致0011,然后将其异或为3,所以0011^0011,这将给您0000
编辑:从评论中提供wiki链接以补充我的解释
编辑:为什么0001^0010
会导致0011
所以最好是一点一点地做。想象一下,操作符迭代两组位并比较它们的对。因此,在本例中,让我们从右向左工作(在本例中,从最不重要到最重要)
因此,将其拼接在一起,您将得到0011
。基本上,获取每对输入并参考真值表以获得结果。注释显示的输出中,x
是一个尚未计算的值
关于碰撞,是的,在这种情况下有很多碰撞。如果我说它是独一无二的,那是一个糟糕的词语选择。我真正的意思是,如果你有2,8,4作为你的值,那么按这个顺序对它们进行异或将总是产生相同的值。详细说明一下,你会看到很多
getHashCode()
方法中的XOR
在字段之间进行异或,因为这是获取对象签名的安全方法。签名的概念是,它就像一个物体的指纹,需要放入32位。这个签名被许多对象用作快速比较(不过,如果您打算使用它,请查看wikipedia的那篇文章,因为您需要小心等式和哈希代码),或者用于某种寻址(例如.net的Dictionary
和Java的HashMap
)
对于我来说,获取盒子指纹的明显解决方案是简单地将值相加,这样,如果其中任何一个值发生变化,您将获得不同的指纹:
bx.Height+bx.Length+bx.Width
考虑到equals操作可能非常昂贵(即非常慢),如果我们需要测试两个框的相等性:
框{5,10,15}
框{30,40,50}
unchecked{…}
块,这是C#特有的,但使用XOR被认为更优雅
我们可以做一件更微妙的事情来提高性能,您将在许多自动生成的hashcode方法(如ReSharper或IntelliJ生成的方法)中看到这一点:
我们可以通过移动(乘以)每个值来使订单变得重要
public int hashCode() {
int result = x;
result = 31 * result ^ y;
result = 31 * result ^ z;
return result;
}
现在发生的是,哈希代码中的每个字段在结果32位中都有一个有效的位置。这意味着两个框:
框{1,20,30}
框{1,30,20}
在Java/Scala和.net framework中,如果重载等于或哈希代码,则必须同时重载另一个。您还必须确保,如果两个对象A和B具有不同的哈希代码,那么对A.Equals(B)的调用必须为false 只需谷歌与之相关的真值表,它看起来像是按位的XOR@Groostav再进一步扩展一下,这里是这样做的,因为对于这些值,
a^b^c
的结果总是相同的。在得到散列之前,他们基本上是将所有的值合并成一个,这样散列对a、b和c的值是唯一的。“按位操作”是什么意思?@YairNevet bitwise表示它正在逐个操作二进制值。正如您在我的示例中看到的,我选择了整数值1、2和3。0001、0010和0011是它们的二进制表示形式。按位运算符对这些值进行操作,而不是对这些值的整数表示进行操作。因此,就像我们使用ASCII(我不知道它是什么字符)一样,某些字符的值为0001,这将被视为与整数1完全相同,因为它们的二进制表示形式是相同的。@YairNevet您可以查看wiki文章以了解更多信息,我认为我的解释不是很清楚。。。但基本上所有类型都在某种程度上用二进制表示,按位运算符处理二进制值,而不是二进制表示的值。@YairNevet整数通常为32或64位,具体取决于您使用的操作系统和语言。可以用4位表示的最大整数值为15。我选择使用那些低数字,因为它们只需要几位。如果您要检查二进制文件中的那些整数,那么这些值将是相同的,但在左边还有28个零。
public int hashCode() {
int result = x;
result = 31 * result ^ y;
result = 31 * result ^ z;
return result;
}