Ответ 1
Прежде всего, вам нужно убедиться, что вы на самом деле печатаете достаточно много цифр, чтобы отобразить все отображаемые значения double
. Вы можете сделать это следующим образом (убедитесь, что вы #include <iomanip>
для этого):
std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << getMax(a) << std::endl;
Во-вторых, numeric_limits<>::min
для этого не подходит. Если ваше начальное значение 1.0
, вы можете использовать numeric_limits<double>::epsilon
, что является наименьшей разницей от 1.0
, которая может быть представлена.
Однако в вашем примере кода начальное значение 32
. Эпсилон не обязательно работает для этого. Вычисление правого эпсилона в этом случае затруднено.
Однако, если вы можете использовать С++ 11 (*) в заголовке cmath
есть функция, которая делает то, что вам нужно std::nextafter
:
#include <iostream>
#include <limits>
#include <iomanip>
#include <cmath>
double getMax(double a)
{
return std::nextafter(a,std::numeric_limits<double>::lowest());
}
int main()
{
double a = 32;
std::cout << std::scientific
<< std::setprecision(std::numeric_limits<double>::max_digits10)
<< getMax(a)
<< std::endl;
return 0;
}
Я также разместил его на liveworkspace.
Объяснить:
double nextafter(double from, double to);
возвращает следующее представимое значение из в направлении to. Поэтому я указал std::numeric_limits<double>::lowest()
в своем вызове, чтобы убедиться, что следующее представляемое значение меньше аргумента.
(*) См. комментарий Tony D ниже. У вас может быть доступ к nextafter()
без С++ 11.