gcc double printf precision - 输出错误

时间:2012-02-29 09:19:03

标签: linux gcc floating-point printf floating-point-precision

#include <stdio.h>
#include <wchar.h> 
int main()
{
    double f = 1717.1800000000001;
    wprintf(L"double      %.20G\n", f);
    return 0;
}

输出(预期如下):

double      1717.1800000000000637
double      1717.1800000000001

这是在Ubuntu 11.10 x64上(但在编译32位时也是如此)。

我试图解决的问题是,在Windows上它输出的数字与代码完全相同,我需要使用低级格式化(swprintf)来像Windows一样工作,以实现可移植性问题。

4 个答案:

答案 0 :(得分:2)

1717.1800000000001不能完全表示为double,因此您只能在f中获得接近它的值。存储在f中的值恰好是1717.180000000000063664629124104976654052734375。

问题是现在windows只输出17位有效数字,虽然要求20位(这是一个已知的错误,AFAIK就在他们的bug数据库中的某个地方)。

如果你不能将字段长度限制为一个合理的值(如"%.17G"),你需要一个包装来模仿这个bug。

答案 1 :(得分:1)

wprintf函数由标准C库实现,而不是由gcc实现。

数字1717.1800000000001在浮点后有13位数。但是,它没有64位二进制浮点格式的精确表示。

格式"%.20G"要求输出20位有效数字,这是1717.1800000000000637中的位数。因此,这个输出是预期的。 Windows标准C库不同地处理格式或进行不正确的舍入。

另一方面,您可以使用"%f"格式在浮点后需要特定的位数,例如"%.13f"将输出四舍五入到浮点后的13位数,并按预期打印1717.1800000000001

答案 2 :(得分:0)

好吧,您的预期输出与您的格式字符串冲突。 “%。20G”表示您需要20位有效数字,这就是您所获得的数字。如果您想要17个有效数字,正如您的预期输出所示,请使用“%。17G”。

答案 3 :(得分:0)

double f = 1717.1800000000001;

这行代码无法准确执行。常量有17个十进制数字的精度,double有15.9。