C 的数字拟合的错误表示



看这个剪子:

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
    //double a = 15670.1;
    //a += 110420;
    double a = 1.1;
    a += 110420;
    printf("%fn",a);
    cout << a << endl;
    a = 1.1;
    a += 11042;
    printf("%fn",a);
    cout << a << endl;
}

结果是:

110421.100000
110421
11043.100000
11043.1

似乎printf工作正常,但是在第一个测试用例中,COUT出了什么问题?它是在第0.1,为什么在第二个测试案例中(COUT)正确?

默认情况下,c 流格式浮点数为6个重要数字,而printf(带有%f)将它们格式化为6个小数位。

您可以使用std::setprecision(在<iomanip>中声明)指定更高的精度:

cout << setprecision(7) << a << endl; // 110421.1

默认情况下,cout的精度太低。您可以使用setprecision()增加它。请参阅以下示例:

#include <iostream>
#include <cstdio>
#include <iomanip>
using namespace std;
int main()
{
    //double a = 15670.1;
    //a += 110420;
    double a = 1.1;
    a += 110420;
    printf("%fn",a);
    cout << setprecision(20) << a << endl;
    a = 1.1;
    a += 11042;
    printf("%fn",a);
    cout << a << endl;
}

第二个测试案例正确的原因是您在那里使用较少的重要数字。

double是6的默认精度。您可以使用6。您可以使用precision()检查此内容:

std::streamsize ss = std::cout.precision();
std::cout << "Initial precision = " << ss << 'n';

在您的示例中:

110421.100000        // oops, truncated to 6 digits, gives 110421 printed
11043.100000         // oops, truncated to 6 **digits**, thus 110431 printed

您现在可以使用setPrecision(int)调整精度:

cout << setprecision(10) << a << endl;

您获得不同结果的原因是因为您要求不同的东西。在printf中,您要固定格式。使用std::cout,您要要求一个可变格式,对应于printf中的"%g"。如果将std::cout设置为固定格式,例如:

std::cout << std::fixed << a;

您应该看到与printf( "%f", a )相同的东西。

对于价值,输出精度默认为6案例(printfstd::cout)。但是精度意味着不同根据格式:以不同的格式对应于"%g",这是指重要的数字;以其他格式(固定和科学),这是指十进制后的数字数。如果是修复了,这可能是一个令人着迷的差异。

(当然,在某个时候,您将在内部遗迹。)

最后,在大型应用程序中,您通常会定义自己自己的操纵器,例如degreesdistanceinterestRate;操纵器将设置许多不同的格式化选项,以便当老板决定您有要更精确地显示学位,您只需要更改操纵器,而不是尝试整个代码库找出哪个"%f"对应于学位。

最新更新