|
Boost Users : |
From: Daniel Krügler (dsp_at_[hidden])
Date: 2005-08-22 01:32:32
Hello,
the current implementation function for hashing of floating point types,
the function template float_hash_value<> in hash.hpp, is implicitely
written for real types where std::numeric_limits<T>::radix == 2.
Although base = 2 is probably the most prominent case, it is not the
only representation compatible with Our Holy Standard. E.g. base 16
floating types are well-known to exist.
The hidden assumption becomes obvious in the formular
std::size_t const length
= (std::numeric_limits<T>::digits +
std::numeric_limits<int>::digits - 1)
/ std::numeric_limits<int>::digits;
which should actually mean (pseudo formular):
std::size_t const length
= (std::numeric_limits<T>::digits2 +
std::numeric_limits<int>::digits - 1)
/ std::numeric_limits<int>::digits;
where the (non-existing) constant digits2 would describe the "Number of
base 2 digits that can be represented without change."
To my opinion boost itself provides a simple helper class, namely
static_log2, which allows the correct implementation by using the
extended formular
#include <boost/integer/static_log2.hpp>
...
std::size_t const length
= (std::numeric_limits<T>::digits *
boost::static_log2<std::numeric_limits<T
>::radix>::value +
std::numeric_limits<int>::digits - 1)
/ std::numeric_limits<int>::digits;
Note that the expression
boost::static_log2<std::numeric_limits<T>::radix>::value is exactly 1
in the usual base-2 case, but e.g. 4 in case of base-16.
My proposed fix is exact in all cases, where radix is a power of 2, in
other cases (like base-10) it would at least be a better approximation
than the current one.
Greetings from Bremen,
Daniel Krügler
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net