I am using a dictionary and I want to overwrite the GetHashCode
function of the Key. But I need a 64-bit hashcode.
Is there any solution?
I am using a dictionary and I want to overwrite the GetHashCode
function of the Key. But I need a 64-bit hashcode.
Is there any solution?
No, you can't. The signature of GetHashCode
is fixed as virtual int GetHashCode()
.
Note that Dictionary<TKey, TValue>
do handle multiple items with the same hashcode. You can try it by overloading a GetHashCode like this:
public override GetHashCode()
{
return 0;
}
That this will make the dictionary quite slow (it will make searching inside it O(n) instead of O(1))!
Dictionary<,>
handles multiple objects with same key by looking at each one of the with the Equals
method (so it's a two-step process, first GetHashCode
, then Equals
between all the items with the same GetHashCode
).
To change a 64 bit GetHashCode to a 32 bit GetHashCode you can simply:
long hash64 = ....;
int hash32 = hash64.GetHashCode();
return hash32;
:-)
or, if you prefer the long way:
long hash64 = ....;
unchecked
{
int hash32 = ((int)hash64) ^ ((int)(hash64 >> 32));
return hash32;
}
If you are interested, here it's explained how Dictionary<,>
works internally. Look under The System.Collections.Generic.Dictionary Class
I have done some research on Zobrist hashes... It seems that you should simply ignore the chances of collisions at 64 bits. If you want to simulate this, you could do something like:
public class HashPiece
{
public readonly long Hash64;
public readonly Piece[] Board = new Piece[64];
public int GetHashCode()
{
return Hash64.GetHashCode();
}
public bool Equals(object other)
{
return this.Hash64 == ((HashPiece)other).Hash64;
}
}
In this example you don't compare the Piece[]
array, and you just hope the full 64 bit hash will be right. Clearly another solution is:
public bool Equals(object other)
{
HashPiece other2 = (HashPiece)other;
if (this.Hash64 != other2.Hash64)
{
return false;
}
return this.Board.SequenceEqual(other.Board);
}
Note that I've found anecdotical experience that the quality of the random number generator, and the single value of the seed value used, can influence the number of collisions.
I have used the below code to generate 64 Bit HashCode,mostly as a substitute for long repetitive strings.
public long ComputeHash(String p_sInput)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] hash = md5.ComputeHash(Encoding.ASCII.GetBytes(p_sInput));
return BitConverter.ToInt64(hash, 0);
}