Soy muy malo en matemáticas y quiero hacer una operación binaria
-
27-10-2019 - |
Pregunta
Tengo el siguiente código:
public void AddHash( int val )
{
m_Hash ^= (val & 0x3FFFFFF);
m_Hash ^= (val >> 26) & 0x3F;
}
Me gustaría mucho saber qué diablos hace, pero estaría satisfecho de saber cómo construir un bool HasHash( int val )
Eso me dice si M_hash tiene ese número o no ...
¿algo como esto?
public bool HasHash( int val )
{
return (m_Hash & val) == 0;
}
Solución
Editar para solucionar el error que encontró @schnaader: ¿Que hace? Este código probablemente quiere rotar val
hacia la izquierda (en sentido horario) por 6 bits y forman la suma de complemento (Editar: no el producto, como había dicho antes) - el xor- de ese valor rotado y el valor actual de m_Hash
para producir un nuevo m_Hash
. Ese nuevo m_Hash
se utilizará la próxima vez AddHash( )
se llama.
Sin embargo, el código tal como está escrito tiene un error: gira solo los 6 bits de orden de alto orden de val
hacia la izquierda, dejando en su lugar los 26 bits de orden bajo de val
. El código luego XORS juntos tres valores:
- el nuevo orden bajo (antiguo orden alto) 6 bits de
val
; - los 26 bits originales, sin desplazarse de 26 bits de
val
; y - el valor actual de
m_Hash
Dejando el resultado en m_Hash
.
¿Cómo lo hace? Puedes simplemente mapearlo y emularlo:
val & 0x3FFFFFF
significa extraer los 26 bits de orden bajo deval
.xor
esos 26 bits con el valor actual dem_Hash
Ahora cambia
val
hacia la derecha de tal manera que los 26 bits de orden bajo dejan el extremo de orden bajo, dejando lo que solía ser los 6 bits de alto orden deval
en el orden bajo 6 bits deval
.- Enmascarar
0x3f
extraer solo esos 6 bits de orden bajo (en caso de que algunos bits extraños se cambiaran a la parte de alto orden deval
). xor
esos 6 bits de orden bajo con el valor actual dem_Hash
para dar el nuevom_Hash
.
Usted sabe que la rotación y el servicio exclusivo son operaciones comunes para calcular un hash.
EDITAR: @Schnaader señaló el error en el código original: ese código olvidó hacer la otra pierna de la rotación: cambiando los 26 bits de orden bajo dejados por 6. Para solucionarlo, el código debería leer algo como:
public void AddHash( int val )
{
m_Hash ^= ((val & 0x3FFFFFF) << 6);
m_Hash ^= (val >> 26) & 0x3F;
}
En cuanto a tu HasHash( )
Función: debes saber que decir
return (m_Hash & val) == 0;
devolverá verdadero en muchas condiciones, incluidos algunas que quizás no desee. Por ejemplo, la función devolverá verdadero si m_Hash == 0xC0
y val == 0x03
.
Otros consejos
Lo que hace el código
Se necesitan los últimos 26 bits de val
y lo combina con m_Hash
usando Xor. Después de eso, combina esto con los primeros 6 bits de val
. Por lo tanto, un entero con 32 bras de longitud se reducirá a 26 bits. De acuerdo con la principio de paloma, esto es no reversible.
Función hashash
Para que no podrás crear un HasHash
función incluso si solo llamó AddHash
solo una vez, porque múltiples valores de entrada en val
dará como resultado lo mismo m_hash
valor.