3

在我之前的问题Comparing a double and int, without cast or conversion中,我发现了两个 double 之间的差异是如何影响比较的。

我遇到了 setprecision() 方法,它有助于显示小数点后的所有数字。

因此,发现 6.15 和 3.15 的差异为:3.00000000000000044408920985006

现在,当它与 3 比较时,它返回一个结果,表明它大于 3。

我如何强制它只占用有限的位数?

当我使用 6.1 和 3.1 时,区别是:2.99999999999999955591079014994

我应该如何计算精度,以便我们知道它实际上等于 3,并且不小于。

4

5 回答 5

4

希望您应该知道浮点/双精度不能以二进制精确表示,并且由于循环小数而发生截断。您与浮点数/双精度整数的比较总是会失败。

即使您使用 setprecision 也不起作用,因为它是一种 iomanip 设置显示精度而不是存储值的方法。

比较双打的可移植方式不是使用“==”运算符,而是执行类似的操作

bool Compare(double a,double b) {
    std::fabs(a - b) < std::numeric_limits<double>::epsilon();
}

您可以使用它来比较双精度与浮点数和/或整数。您还可以为 float 编写类似的比较函数

bool Compare(float a,float b) {
    std::fabs(a - b) < std::numeric_limits<float>::epsilon();
}
于 2012-05-02T19:41:37.337 回答
3

在对您的另一个问题的评论中,您已经被指向这篇关于浮点数的出色论文。非常值得一读。

关于您的特定问题,一种标准方法是定义一个容差,以便在双打之间进行比较。例如,如果您有两个双精度ab,并希望确定是否a大于(另一个双精度)b的容差范围内eps,您可能会执行以下操作:

if (a - b > eps) {
  // a is greater than b
} else {
  // a is not greater than b
}

或者,如果您想知道a等于b指定的容差eps,您可以执行以下操作:

if (std::abs(a - b) <= eps) {
  // a and b are equal within the set tolerance
} else {
  // a and b are not equal within the set tolerance
}

正如其他人所指出的,C++ 提供了一些开箱即用的有用函数来执行这些比较。看看std::absstd::numeric_limits和这篇关于 SO的好帖子。

于 2012-05-02T19:45:59.523 回答
2

这是一个比较函数,用于确定两个数字是否在一个 LSB 内。

bool Compare(double a, double b)
{
    return (a <= std::nextafter(b, abs(1.1*b))) && (b <= std::nextafter(a, abs(1.1*a)));
}

std::nextafter对 C++11 来说是新的,但在早期的编译器中提供了版本。请参阅生成下一个最大或最小的可表示浮点数而不进行位旋转

于 2012-05-02T19:51:23.673 回答
1

setprecision允许您选择向流中吐出多少位数字。它不决定要考虑的位数。出于舍入目的,请使用 中的舍入函数之一<cmath>

于 2012-05-02T19:39:52.340 回答
0

float 和 double 的精度位数实际上分别取决于它们的大小。这就是为什么 float 通常比 double 精度低。您可以使用

    std::cout<<std::setprecision(desired no);

    float a=(desired no);

现在您已经成功设置了浮点数的精度。同样可以对其他适当的数据类型进行同样的操作,包括双精度数。 警告不要将精度设置为大于数据类型必须提供的精度。Double 具有 15 到 18 位精度,而浮点型只有 6 到 9 位精度。

于 2017-05-31T06:59:56.483 回答