のデフォルトのハッシュの背後にはunordered_map
、指定された値のハッシュを計算するためのstd::hash
構造体があります。operator()
std::hash<float>
およびを含む、このテンプレートのデフォルトの特殊化のセットを使用できますstd::hash<double>
。
私のマシン(LLVM + clang)では、これらは次のように定義されています
template <>
struct hash<float> : public __scalar_hash<float>
{
size_t operator()(float __v) const _NOEXCEPT
{
// -0.0 and 0.0 should return same hash
if (__v == 0)
return 0;
return __scalar_hash<float>::operator()(__v);
}
};
ここで、__scalar_hash
は次のように定義されます。
template <class _Tp>
struct __scalar_hash<_Tp, 0> : public unary_function<_Tp, size_t>
{
size_t operator()(_Tp __v) const _NOEXCEPT
{
union
{
_Tp __t;
size_t __a;
} __u;
__u.__a = 0;
__u.__t = __v;
return __u.__a;
}
};
基本的にハッシュは、和集合の値をソース値に設定し、次に、として大きい部分だけを取得することによって構築されますsize_t
。
したがって、パディングを取得するか、値を切り捨てますが、数値の生のビットがハッシュの計算に使用されることがわかるため、これは==
演算子として正確に機能することを意味するため、実際には問題ではありません。同じハッシュ(切り捨てによって与えられる衝突を除く)を持つ2つの浮動小数点数は、同じ値でなければなりません。