为什么 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::fixed
和 setprecision
,它将显示精度要求的任意数字,而不会舍入和截断。
至于为什么四舍五入占输出...
让我们让您的代码也打印一些其他内容:
#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"
。
不幸的是,处理double
s和float
s时,这种事情是正常的。
这是我的想法:
#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::fixed
和 setprecision
,它将显示精度要求的任意数字,而不会舍入和截断。
至于为什么四舍五入占输出...
让我们让您的代码也打印一些其他内容:
#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"
。
不幸的是,处理double
s和float
s时,这种事情是正常的。