我的数学非常糟糕,我想做二进制操作

时间:2011-04-30 18:53:07

标签: c# binary-operators

我有以下代码:

    public void AddHash( int val )
    {
        m_Hash ^= (val & 0x3FFFFFF);
        m_Hash ^= (val >> 26) & 0x3F;
    }

我非常想知道它的作用,但我会很高兴知道如何建立一个bool HasHash( int val )来告诉我m_Hash是否有这个数字......

这样的事情?

    public bool HasHash( int val )
    {
        return (m_Hash & val) == 0;
    }

2 个答案:

答案 0 :(得分:3)

代码的作用

它使用val的最后26位,并使用XOR将其与m_Hash结合使用。之后,它将它与val的前6位组合在一起。因此,32位长度的整数将减少到26位。根据{{​​3}},这是可逆。

HasHash功能

即使您只调用HasHash一次,也无法创建AddHash函数,因为val中的多个输入值将导致相同m_hash价值。

答案 1 :(得分:3)

编辑以解决@schnaader发现的错误:它的作用是什么?此代码可能 希望 向左(顺时针)向左旋转val 6位并形成补码和(编辑:不是产品,如我之前说过) - 旋转值的xor - 和m_Hash的当前值,以产生新的m_Hash。新的m_Hash将在下次调用AddHash( )时使用。

但是,编写的代码有一个错误:它只向左旋转val的高位6位,留下val的低位26位。然后代码将三个值组合在一起:

  1. val的新低位(旧高位)6位;
  2. 原始的,未移位的低位26位val;和
  3. m_Hash
  4. 的当前值

    将结果保留在m_Hash中。

    它是如何做到的?您可以将其映射并模拟它:

    1. val & 0x3FFFFFF表示提取val的低位26位。
    2. xor这些26位,当前值为m_Hash

    3. 现在向右移动val,使低位26位从低位端下降,留下曾经是低位val的高位6位 - 订购val的6位。

    4. 使用0x3f进行掩码,仅提取那些低位6位(如果某些无关位被移位到val的高位部分)。
    5. xor那些低位6位,当前值为m_Hash,以提供新的m_Hash
    6. 您知道旋转和异或是计算哈希值时的常见操作。

      编辑: @schnaader指出了原始代码中的错误:代码忘记了旋转的另一条腿:将低位26位左移6位。要解决这个问题,代码应该是这样的:

      public void AddHash( int val )
      {
        m_Hash ^= ((val & 0x3FFFFFF) << 6);
        m_Hash ^= (val >> 26) & 0x3F;
      }
      

      至于你的HasHash( )功能:你应该知道说

      return (m_Hash & val) == 0;

      将在许多条件下返回TRUE,包括您可能不想要的一些条件。例如,如果m_Hash == 0xC0val == 0x03,则函数将返回TRUE。