为什么'科学'改变精确度的含义'?

时间:2018-02-06 11:23:18

标签: c++11

这是一个MWE:

#include <iostream>

int main()
{
    std::cout.precision(17);
    std::cout << 1.2345678901234567890 << '\n';
    std::cout.setf(std::ios_base::scientific);
    std::cout.precision(17);
    std::cout << 1.2345678901234567890 << '\n';
}

在我的机器上打印:

1.2345678901234567
1.23456789012345669e+00

最后一个输出有一个额外的数字(18而不是我明确请求的17。为什么呢?

2 个答案:

答案 0 :(得分:3)

follows the rules of printf,在从流状态汇编了格式说明符之后。

int main()
{
    std::printf("%.17g\n", 1.2345678901234567890);
    std::printf("%.17f\n", 1.2345678901234567890);
    std::printf("%.17e\n", 1.2345678901234567890);

    std::printf("%.17g\n", 1234567890.1234567890);
    std::printf("%.17f\n", 1234567890.1234567890);
    std::printf("%.17e\n", 1234567890.1234567890);
}

既不std::ios_base::scientific也不std::ios_base::fixed,格式为"%.17g",对应 17位数

std::ios_base::scientific格式为"%.17e",对应小数点后的17位数加上指数。由于小数点前只有一位数字,因此 18总数

使用std::ios_base::fixed格式为"%.17f",其格式为小数点后的17位数。小数点前可能有多个数字,这会导致 18或更多位数

答案 1 :(得分:2)

认为这是因为数字的计算方式。考虑一个改变的例子:

std::cout.precision(4);
std::cout << 12.345678901234567890 << '\n';
std::cout.setf(std::ios_base::scientific);
std::cout.precision(4);
std::cout << 12.345678901234567890 << '\n';

在这种情况下,输出为:

12.35
1.2346e+01

正如您可以清楚地看到的那样,precision表示常规浮动形式的“总位数”,以及使用科学记数法时的“小数位数”(因为它意味着前面总是有一位数字)小数点)。