如何打印一个小于另一个double值的double值?

时间:2013-02-26 07:09:46

标签: c++ number-formatting

实际上我正在研究c ++中的范围表达式。所以我想要的是,如果我有任何表达式,如

x<1

然后我的

double getMax(...);

应该在数字行上返回一个在1.000(双精度)之前的双精度值。

我试过这个

double getMax(double& a)
{
    return (a-numeric_limits<double>::min());
}

但我仍然得到与回报声明相同的价值。

我认为C ++在cout语句中将其转换为最接近的双倍。

int main()
{
    double a = 32;
    cout<<scientific<<getMax(a)<<endl;
    return 0;
}

输出:

3.200000e+001

2 个答案:

答案 0 :(得分:10)

首先,您需要确保实际打印足够多的数字,以确保显示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);

返回from的方向的下一个可表示值。所以我在调用中指定了std::numeric_limits<double>::lowest(),以确保您获得下一个可表示的值小于参数。

(*)请参阅下面的Tony D的评论。您可以在没有C ++ 11的情况下访问nextafter()

答案 1 :(得分:0)

我认为你有正确的想法。 查看Setting the precision of a double without using stream (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