РЕДАКТИРОВАТЬ, чтобы исправить ошибку, обнаруженную @schnaader: Что она делает?Этот код, вероятно, хочет, чтобы повернул val
влево (по часовой стрелке) на 6 битов и сформировал сумму единиц дополнения (редактировать: не продукт, как я сказалдо) - xor - этого повернутого значения и текущего значения m_Hash
, чтобы получить новое m_Hash
.Этот новый m_Hash
будет использоваться при следующем вызове AddHash( )
.
Однако в написанном коде есть ошибка: он вращает только старшие 6 битов val
влево, оставляя впоместите младшие 26 бит val
.Затем код объединяет воедино три значения:
- новые 6 битов старшего разряда старшего разряда
val
; - исходные 26 битов младшего разряда несмещенного значения
val
;и - текущее значение
m_Hash
, оставляя результат в m_Hash
.
Как это получается?Вы можете просто отобразить его и эмулировать:
val & 0x3FFFFFF
означает извлечение младших 26 битов val
. xor
те 26 битов с текущим значением m_Hash
теперь смещены val
вправо так, что младшие 26 битов уменьшаютсяот младшего конца, оставляя то, что раньше было старшими 6 битами val
в младших 6 битах val
.
- Маска с
0x3f
для извлечениятолько те младшие 6 битов (в случае, если некоторые посторонние биты были сдвинуты в старшую часть val
). xor
эти младшие 6 битов с текущим значением m_Hash
вдайте новый m_Hash
.
Вы знаете, что вращение и исключающее ориентирование являются общими операциями при вычислении хэша.
РЕДАКТИРОВАТЬ: @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 при многих условияхitions, включая некоторые, которые вы, возможно, не хотите.Например, функция вернет TRUE, если m_Hash == 0xC0
и val == 0x03
.