Sto leggendo tramite Chapter 3 di di Joshua Bloch Java efficace. In Articolo 8: ignorare sempre hashCode quando si modifica uguale, l'autore utilizza il passo seguente che unisce nella sua funzione di hashing:Per la moltiplicazione di interi, l'overflow e la perdita di informazioni
result = 37 * result + c;
Poi spiega perché 37 è stato scelto (enfasi aggiunta):
Il moltiplicatore 37 è stato scelto perché è un numero primo dispari. Se fosse pari e la moltiplicazione traboccava, le informazioni andrebbero perse perché la moltiplicazione di due equivaleva allo spostamento. I vantaggi dell'utilizzo di un numero primo sono inferiori a , ma è normale utilizzare i numeri primi a questo scopo.
La mia domanda è perché è importante che il fattore che unisce (37) è strano? Il superamento della moltiplicazione non determinerebbe una perdita di informazioni indipendentemente dal fatto che il fattore fosse pari o dispari?
Ah, quindi non è solo un po 'di perdita di informazioni che è possibile ottenere da un overflow di cui siamo preoccupati, è * completa * la perdita di informazioni che è possibile ottenere dall'azzeramento del risultato? –
@BilltheLizard: in realtà, sono i dati di più proprietà che si emulano a vicenda. Assumendo tre proprietà a, b, e c usando l'algoritmo di cui sopra 'result = 2 * (2 * a + b) + c', puoi vedere che ci sarà una duplicazione in molti set forse comuni di' a, b, c'. Se si utilizza un primo dispari come costante, la possibilità di avere un set con gli stessi valori hash diventa molto inferiore. –
Il problema si manifesta anche prima di aver azzerato completamente il risultato. Considera di moltiplicare un hash a 8 bit con un moltiplicatore di due solo una volta: è iniziato con 256 valori possibili e termina con 128 valori possibili. –