1212#include < boost/decimal/decimal_fast64_t.hpp>
1313#include < boost/decimal/decimal_fast128_t.hpp>
1414#include < boost/decimal/detail/config.hpp>
15+ #include < boost/decimal/detail/cmath/normalize.hpp>
1516
1617#ifndef BOOST_DECIMAL_BUILD_MODULE
1718#include < functional>
@@ -26,8 +27,10 @@ struct hash<boost::decimal::decimal32_t>
2627 // Since the underlying type is a std::uint32_t, we will rely on its hash function from the STL
2728 auto operator ()(const boost::decimal::decimal32_t & v) const noexcept -> std::size_t
2829 {
30+ const auto normalized_v {boost::decimal::normalize (v)};
31+
2932 std::uint32_t bits;
30- std::memcpy (&bits, &v , sizeof (std::uint32_t ));
33+ std::memcpy (&bits, &normalized_v , sizeof (std::uint32_t ));
3134
3235 return std::hash<std::uint32_t >{}(bits);
3336 }
@@ -39,8 +42,10 @@ struct hash<boost::decimal::decimal64_t>
3942 // Since the underlying type is a std::uint64_t, we will rely on its hash function from the STL
4043 auto operator ()(const boost::decimal::decimal64_t & v) const noexcept -> std::size_t
4144 {
45+ const auto normalized_v {boost::decimal::normalize (v)};
46+
4247 std::uint64_t bits;
43- std::memcpy (&bits, &v , sizeof (std::uint64_t ));
48+ std::memcpy (&bits, &normalized_v , sizeof (std::uint64_t ));
4449
4550 return std::hash<std::uint64_t >{}(bits);
4651 }
@@ -57,8 +62,10 @@ struct hash<boost::decimal::decimal128_t>
5762 // Take the xor of the two words and hash that
5863 auto operator ()(const boost::decimal::decimal128_t & v) const noexcept -> std::size_t
5964 {
65+ const auto normalized_v {boost::decimal::normalize (v)};
66+
6067 boost::int128::uint128_t bits;
61- std::memcpy (&bits, &v , sizeof (boost::int128::uint128_t ));
68+ std::memcpy (&bits, &normalized_v , sizeof (boost::int128::uint128_t ));
6269
6370 return std::hash<std::uint64_t >{}(bits.high ^ bits.low );
6471 }
0 commit comments