Fix WeakHash32 for floating point types

This commit is contained in:
Sergey Skvortsov 2022-06-26 21:24:41 +03:00
parent e7eb10ffd1
commit b7bfb6abb0

View File

@ -73,7 +73,7 @@ inline DB::UInt64 intHashCRC32(DB::UInt64 x, DB::UInt64 updated_value)
}
template <typename T>
requires (sizeof(T) > sizeof(DB::UInt64))
requires std::has_unique_object_representations_v<T> && (sizeof(T) % sizeof(DB::UInt64) == 0)
inline DB::UInt64 intHashCRC32(const T & x, DB::UInt64 updated_value)
{
const auto * begin = reinterpret_cast<const char *>(&x);
@ -86,6 +86,25 @@ inline DB::UInt64 intHashCRC32(const T & x, DB::UInt64 updated_value)
return updated_value;
}
template <std::floating_point T>
requires(sizeof(T) <= sizeof(UInt64))
inline DB::UInt64 intHashCRC32(T x, DB::UInt64 updated_value)
{
static_assert(std::numeric_limits<T>::is_iec559);
// In IEEE 754, the only two floating point numbers that compare equal are 0.0 and -0.0.
// See std::hash<float>.
if (x == static_cast<T>(0.0))
return intHashCRC32(0, updated_value);
UInt64 repr;
if constexpr (sizeof(T) == sizeof(UInt32))
repr = std::bit_cast<UInt32>(x);
else
repr = std::bit_cast<UInt64>(x);
return intHashCRC32(repr, updated_value);
}
inline UInt32 updateWeakHash32(const DB::UInt8 * pos, size_t size, DB::UInt32 updated_value)
{