#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一样工作,以实现可移植性问题。
答案 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。