
Boost Users : 
From: Daniel Krügler (dsp_at_[hidden])
Date: 20050822 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 wellknown 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 (nonexisting) 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 base2 case, but e.g. 4 in case of base16.
My proposed fix is exact in all cases, where radix is a power of 2, in
other cases (like base10) it would at least be a better approximation
than the current one.
Greetings from Bremen,
Daniel Krügler
Boostusers 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