首先,您需要确保实际打印足够多的数字以确保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
. Epsilon 不一定适用于此。在这种情况下计算正确的 epsilon 是很困难的。
但是,如果您可以使用 C++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 的方向上返回 from 的下一个可表示值。因此,我std::numeric_limits<double>::lowest()
在调用中指定以确保您获得的下一个可表示值小于参数。
(*)请参阅下面的 Tony D 评论。您可以在nextafter()
没有 C++11 的情况下访问。