So I was looking for a way to hash 2D coordinates (a pair of 32-bit integers) so I could deterministically compare and store them in a c++ set, and I found a method that I implemented like this:
int hashx = std::hash<int>()(x);
int hashy = std::hash<int>()(y);
hash = hashx ^ (hashy << 1);
It seems to work, based on the results. Then again, the result is a 4-byte integer and it could be that I'm just not getting any collisions because the domain is so huge.
So my question is: what's going on here? What does std::hash do with integers, and what exactly does that bit-shifting and XORing operation do to combine the results? Is this actually a good hashing method?
I know nothing about std:hash, but... (assuming that it does not change the integer) oh gods what? You're literally XORing hashx with hashy multiplied by two (except more efficient because bitshift).
Every time you try to hash a pair of numbers where x=y*2 the hash will be
zero.
(You can test it to find out if std::hash<int>()(x) is returning something other than x, and if so maybe it's not as huge a problem? Because then the hash won't be zero when x=y*2, it'll only be zero if hashx=hashy*2, and if hashx and hashy are evenly distributed across all possible int32 values, it'd be a lot less likely - like, really unlikely.)
(Even if it was the case, iirc it'd really be a huge problem if you were trying to compare hashes to see if something is identical to something else)