为什么在OR上使用XOR?

时间:2018-12-05 04:19:40

标签: c xor

The C code of MurmurHash3包含以下部分:

  uint64_t k1 = 0;
  uint64_t k2 = 0;

  switch(len & 15)
  {
  case 15: k2 ^= ((uint64_t)tail[14]) << 48;
  case 14: k2 ^= ((uint64_t)tail[13]) << 40;
  case 13: k2 ^= ((uint64_t)tail[12]) << 32;
  case 12: k2 ^= ((uint64_t)tail[11]) << 24;
  case 11: k2 ^= ((uint64_t)tail[10]) << 16;
  case 10: k2 ^= ((uint64_t)tail[ 9]) << 8;
  case  9: k2 ^= ((uint64_t)tail[ 8]) << 0;

tail的类型为uint8_t *

据我所知,它与OR操作没有什么不同。在这里使用XOR有什么区别?是优化吗?如果是,那是什么?还是我遗漏了这两个操作员的行为差异?

我已经知道XOR和OR之间的区别。但是在这种情况下,由于该值在开始时被清零并且异或的值不重叠,所以该行为与OR不应有任何不同。因此,我想问一问为什么作者选择它而不是OR(它比XOR imho更好地传达了意图)。

2 个答案:

答案 0 :(得分:1)

是的,在这种情况下,它们是完全等效的。此外,由于它们是等效的,因此编译器可以单独使用它进行优化。编译时,您无法保证它实际上是xor xor。实际上,从更一般的层面上讲,只要编译器生成的代码的可观察行为相同,就不能保证它会是它们中的任何一个。

使用xor的合理原因是,这是有问题的程序员首先想到的东西,或者代码最初是用很重要的方式编写的,但是后来又变成了不需要的版本物。但是由于在这种情况下它们是等效的,所以很难知道。

答案 1 :(得分:0)

  

为什么在OR上使用XOR?

如果人们可以在此限制性代码中使用|^来获取和存档相同的功能,则首选的应该反映更大的问题。

^保留熵@Nominal Animal

当代码试图形成哈希时(如MurmurHash3),^|更好。 ^翻转位通常会导致1和0的合理分布。 |偏向1。

许多散列算法会像binary addition with no carries一样“添加” ab,也就是说a ^ b而不是a | b。因此,在这种哈希算法环境中,^传达了更好的算法意图。


有时我会遇到确实使用|的哈希代码,但不幸的是,结果会产生偏差,而^可以正常工作。 IMO,哈希码中的|是一个可能会产生偏见的危险信号。