Я очень плохо в математике и хочу сделать бинарную операцию
-
27-10-2019 - |
Вопрос
У меня есть следующий кусок кода:
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;
}
Решение
Изменить, чтобы исправить ошибку, которую нашел @Schnaader: Что оно делает? Этот код, вероятно, хочет вращать val
слева (по часовой стрелке) на 6 бит и образуйте сумму с надписью (Редактировать: не продукт, как я уже говорил) - XOR- этого повернутого значения и текущего значения m_Hash
Чтобы получить новый m_Hash
. Анкет Это новое m_Hash
будет использоваться в следующий раз AddHash( )
называется.
Тем не менее, код, написанный, имеет ошибку: он поворачивает только 6 бит высокого порядка 6 val
влево, оставляя на месте 26 битов низкого порядка val
. Анкет Код затем xors вместе три значения:
- Новый низкий (старый высокий заказ) 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, если m_Hash == 0xC0
а также val == 0x03
.
Другие советы
Что делает код
Это требует последних 26 кусочков val
и объединяет его с m_Hash
с использованием XOR. Анкет После этого это объединяет это с первыми 6 битами val
. Анкет Таким образом, целое число с длиной 32 бит будет уменьшено до 26 бит. Согласно Принцип голубя, Это нет обратимый.
Хашаш функция
Так что вы не сможете создать HasHash
функционируйте, даже если вы только вызвали AddHash
только один раз, потому что несколько входных значений в val
приведет к тому же m_hash
ценность.