如何打印刚好小于另一个双精度值的双精度值? 实际上,我正在研究C++中的范围表达式。所以我想要的是如果我有这样的表情 x<1
应在数字行上返回刚好在1.000(双精度)之前的双精度值 我试过这么做如何打印刚好小于另一个双精度值的双精度值? 实际上,我正在研究C++中的范围表达式。所以我想要的是如果我有这样的表情 x<1,c++,number-formatting,C++,Number Formatting,应在数字行上返回刚好在1.000(双精度)之前的双精度值 我试过这么做 double getMax(double& a) { return (a-numeric_limits<double>::min()); } 我认为你的想法是对的。 与其说查看问题,不如说查看他们给出的使用precision的示例。你可能想试试打印精度为53的东西 我通常认为“接近但不完全”的方式包括设置一个差异阈值(通常称为epsilon)。在这种情况下,您不会使用getMax函数,而是在小于
double getMax(double& a)
{
return (a-numeric_limits<double>::min());
}
我认为你的想法是对的。 与其说查看问题,不如说查看他们给出的使用
precision
的示例。你可能想试试打印精度为53的东西
我通常认为“接近但不完全”的方式包括设置一个差异阈值(通常称为epsilon)。在这种情况下,您不会使用getMax
函数,而是在小于的情况下使用epsilon。(您可以使用epsilon值和运算符重载创建一个类。我倾向于像瘟疫一样避免运算符重载。)
基本上,您需要:
bool lessThanEpsilon(double number, double lessThan, double epsilon)
{
return (lessThan - number >= epsilon);
}
当然还有其他种类。如果Math.abs(number-Equals)
,首先,您需要确保实际打印足够多的数字,以确保显示所有可表示的双精度
值。您可以按如下方式执行此操作(请确保您为此#包括):
我也穿上了
解释:
double nextafter(double from, double to);
返回从到方向上的下一个可表示值。因此,我在调用中指定了std::numeric\u limits::lowest()
,以确保获得的下一个可表示值小于参数
(*)见下面Tony D的评论。不使用C++11,您可以访问nextafter()
。下面所有的内容都说明,getMax
对于开放区间没有意义,应该精确返回1。注释行不应该是a-a*..::epsilon()
?哦,好吧,它将向零舍入。如果四舍五入,2*a*…::epsilon()
将是正确的值,但如果不四舍五入,则值将大两倍。哎哟,哎哟。@JanHudec10
是我在提交代码之前运行的一个测试的遗留物。我把它拿走了。我不知道与a相乘是否正确。选择正确的因子超出了我的知识范围——我的主要观点是在C++11中使用nextafter
。为了正确计算ε,其他人可能会想出一个答案。另一件事是我怀疑ε对于之前的可表示值不正确。因为在1之前,下一个值是1.fffffffffffp-1,即1-253,但ε是2-52。+1/值得注意的是,某些系统在提供的C库中提供了此功能,因此即使不使用C++11,您也可以使用它(不可移植):例如(标准:C99,POSIX.1-2001)
3.200000e+001
bool lessThanEpsilon(double number, double lessThan, double epsilon)
{
return (lessThan - number >= epsilon);
}
std::cout << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << getMax(a) << std::endl;
#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;
}
double nextafter(double from, double to);