为什么 cout 的默认精度不影响评估结果?

Why cout's default precision doesn't effect evaluated result?

这是我的想法:

 #include <iostream>
 #include <iomanip>

  int main ()
 {
    double x = 10-9.99;
   std::cout << x << std::endl;
   std::cout << std::setprecision (16);
   std::cout << x;
   return 0;
  }

上面的程序通过在setprecision()之前评估x和一个不完全等于0.01的长数来打印0.01,因为setprecision()之后的x.cout在我的打印浮点数时默认精度为16机器。如果精度为 16,上面的值应该类似于 0.0100000000000000 但它仍然是 0.01 但是当我将精度 () 设置为 16 时,程序会打印一个包含 16 位数字的长数字。所以我的问题是,为什么 cout 不根据类型默认精度打印所有数字。为什么我们需要强制cout(通过使用setprecision())打印所有数字?

why cout doesn't prints all the digits according to types default precision.

如果您同时使用 std::fixedsetprecision,它将显示精度要求的任意数字,而不会舍入和截断。

至于为什么四舍五入占输出...

让我们让您的代码也打印一些其他内容:

#include <iostream>
#include <iomanip>

int main ()
{
    double x = 10-9.99;
    std::cout << x << '\n';
    std::cout << std::setprecision (16);
    std::cout << x << '\n';
    std::cout << 0.01 << '\n';
    std::cout << std::setprecision (18);
    std::cout << x << '\n';
    std::cout << 0.01 << '\n';
    std::cout << x - 0.01 << '\n';
}

和输出(在一个特定的 compiler/system 上):

0.01  // x default
0.009999999999999787  // x after setprecision(16)
0.01  // 0.01 after setprecision(16)
0.00999999999999978684   // x after setprecision(18)
0.0100000000000000002    // 0.01 after setprecision(18)
-2.13370987545147273e-16  // x - 0.01

如果我们看看 0.01 是如何以 18 位精度直接编码的...

0.0100000000000000002
   123456789012345678  // counting digits

...我们可以清楚地看到为什么它会在输出期间以任何精度被截断为 "0.01",最高为 17。

您还可以清楚地看到 x 中的值与通过直接编码 0.01 创建的值不同 - 这是允许的,因为它是计算的结果,并且取决于 double 或 CPU - 注册 9.99 的近似值,其中一个或两个都导致了差异。该错误足以阻止以精度 16 舍入到 "0.01"

不幸的是,处理doubles和floats时,这种事情是正常的。