Double has range more than a 64-bit integer, but its precision is less dues to its representation (since double is 64-bit as well, it can't fit more actual values). So, when representing larger integers, you start to lose precision in the integer part.
#include <boost/cstdint.hpp>
#include <limits>
template<typename T, typename TFloat>
void
maxint_to_double()
{
T i = std::numeric_limits<T>::max();
TFloat d = i;
std::cout
<< std::fixed
<< i << std::endl
<< d << std::endl;
}
int
main()
{
maxint_to_double<int, double>();
maxint_to_double<boost::intmax_t, double>();
maxint_to_double<int, float>();
return 0;
}
This prints:
2147483647
2147483647.000000
9223372036854775807
9223372036854775800.000000
2147483647
2147483648.000000
Note how max int
can fit into a double
without loss of precision and boost::intmax_t
(64-bit in this case) cannot. float
can't even hold an int
.
Now, the question: is there a way in C++ to check if the entire range of a given integer type can fit into a loating point type without loss of precision?
Preferably,
- it would be a compile-time check that can be used in a static assertion,
- and would not involve enumerating the constants the compiler should know or can compute.