c ++错误表示一个数字拟合为double

时间:2014-03-10 18:31:08

标签: c++ floating-point floating-point-precision

看看这个剪辑:

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

结果是:

110421.100000
110421
11043.100000
11043.1

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

4 个答案:

答案 0 :(得分:2)

默认情况下,C ++流将浮点值格式化为6位有效数字,而printf使用%f将其格式化为6位小数。

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

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

答案 1 :(得分:0)

默认情况下,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("%f\n",a);
    cout << setprecision(20) << a << endl;
    a = 1.1;
    a += 11042;
    printf("%f\n",a);
    cout << a << endl;
}

第二个测试用例正确的原因只是你在那里使用较少的有效数字。

答案 2 :(得分:0)

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;

答案 3 :(得分:0)

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

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

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

对于它的价值,两者的输出精度默认为6 案例(printfstd::cout)。但精确意味着不同 根据格式的东西:以不同的格式 对应于"%g",表示总数 有效数字;在其他格式(固定和科学), 它表示小数点后的位数;如果是 固定,这可能是一个显着的差异。

(当然,在某些时候,你将失去精确度 内部论坛。)

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