其实我正在用c ++编写范围表达式。所以我想要的是如果我有任何表达式
x<1
然后我的
double getMax(...);
应该在数字行上返回一个在1.000(双精度)之前的双精度值。
我试过这样做
double getMax(double& a)
{
return (a-numeric_limits<double>::min());
}
但我仍然得到与回报声明相同的价值。
我认为C ++在cout语句中将它转换为最接近的double。
int main()
{
double a = 32;
cout<<scientific<<getMax(a)<<endl;
return 0;
}
输出:
3.200000e+001
首先,您需要确保实际打印足够多的数字以确保所有可表示的值 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并不一定适用于此。在这种情况下计算正确的eps是很困难的。
但是,如果您可以使用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);
返回from的方向的下一个可表示的值。所以我指定了 std::numeric_limits<double>::lowest()
在我的电话中,以确保您获得下一个可表示的价值 少于 这个论点。
(*)请参阅下面的Tony D的评论。您可以访问 nextafter()
没有C ++ 11。
我认为你有正确的想法。
查看 不使用流设置double的精度(ios_base :: precision) 问题不在于此,而在于他们使用的例子 precision
。您可能想要尝试像精度为53的打印。
我通常看到“接近但不完全”的方式涉及设置差异阈值(通常称为epsilon)。在这种情况下,你不会使用 getMax
功能,但有一个epsilon用于你的使用小于。 (你可以用epsilon值和运算符重载来完成一个类。我倾向于避免像瘟疫这样的运算符重载。)
基本上,你需要:
bool lessThanEpsilon(double number, double lessThan, double epsilon)
{
return (lessThan - number >= epsilon);
}
当然还有其他品种。等于会检查 if Math.abs(number - equals) < epsilon