Is the floating point specialisation of std::hash
(say, for double
s or float
s) reliable regarding almost-equality? That is, if two values (such as (1./std::sqrt(5.)/std::sqrt(5.))
and .2
) should compare equal but will not do so with the ==
operator, how will std::hash
behave?
So, can I rely on a double
as an std::unordered_map
key to work as expected?
I have seen "Hashing floating point values" but that asks about boost; I'm asking about the C++11 guarantees.
std::hash<const char*> produces a hash of the value of the pointer (the memory address), it does not examine the contents of any character array.
That means you can only have 256 unique hashes of arbitrary inputs. Since you can definitely create more than 256 different strings, there is no way the hash would be unique for all possible strings.
using c++11, you can: #include <string> #include <unordered_map> std::size_t h1 = std::hash<std::string>{}("MyString"); std::size_t h2 = std::hash<double>{}(3.14159);
std::hash
has same guarantees for all types over which it can
be instantiated: if two objects are equal, their hash codes will
be equal. Otherwise, there's a very large probability that they
won't. So you can rely on a double
as a key in an
unordered_map
to work as expected: if two doubles are not
equal (as defined by ==
), they will probably have a different
hash (and even if they don't, they're different keys, because
unordered_map
also checks for equality).
Obviously, if your values are the results of inexact
calculations, they aren't appropriate keys for unordered_map
(nor perhaps for any map).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With