Podwójny ma zakres większy niż 64-bitowa liczba całkowita, ale jego dokładność jest mniejsza niż składki do jej reprezentacji (ponieważ podwójne to również 64-bitowe, może dopasowują więcej rzeczywistych wartości). Tak więc, gdy reprezentujesz większe liczby całkowite, zaczynasz tracić precyzję w części całkowitej.Znajdź maksymalną liczbę całkowitą, którą może obsłużyć typ zmiennoprzecinkowy bez utraty precyzji.
#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;
}
Drukuje:
2147483647
2147483647.000000
9223372036854775807
9223372036854775800.000000
2147483647
2147483648.000000
Zauważ max int
może pasować do double
bez utraty precyzji i boost::intmax_t
(64-bit w tym przypadku) nie może. float
nie może nawet posiadać numeru int
.
Teraz pytanie: jest sposób w C++, aby sprawdzić, czy cały zakres danego typu integer może pasować do typu punktu loating bez utraty precyzji?
Korzystnie
- byłoby sprawdzenie kompilacji, które mogą być używane w statycznym twierdzenia
- i nie pociąga za sobą wyliczanie stałych kompilator powinien wiedzieć czy można obliczyć.
Dlaczego trzeba sprawdzić? Część całkowita ma 52 bity precyzji, więc to, ile dostajesz. –
Po ustaleniu limitu nie możesz zdefiniować CONST? –
@Billy: _Technically_ C++ nie wymaga zmiennoprzecinkowego IEEE 754, więc zakładając, że implementacja wykorzystuje IEEE 754, nie jest przenośna (fakt, że IEEE 754 jest wszechobecny). –