谁能解释我printf中的[.precision]如何与说明符“%g”一起使用?以下输出让我很困惑:

double value = 3122.55;
printf("%.16g\n", value); //output: 3122.55
printf("%.17g\n", value); //output: 3122.5500000000002

我了解到%g使用最短的表示形式。

但是以下输出仍然使我感到困惑
printf("%.16e\n", value); //output: 3.1225500000000002e+03
printf("%.16f\n", value); //output: 3122.5500000000001819
printf("%.17e\n", value); //output: 3.12255000000000018e+03
printf("%.17f\n", value); //output: 3122.55000000000018190

我的问题是:为什么%.16g给出了确切的数字而%.17g无法给出?

看来16位有效数字是准确的。谁能告诉我原因?

最佳答案

%g使用最短的表示形式。
浮点数usually aren't stored作为基本10中的数字,但为2(性能,大小,实用性原因)。但是,无论您使用哪种表示形式,总会有一些有理数无法以任意大小限制来表示变量来存储它们。
当指定%.16g时,就是说您要用最短的16有效数字来表示数字。
如果最短表示形式的位数超过16数字,则printf会通过在最后切掉2数字,从而缩短数字字符串,剩下3122.550000000000(实际上是最短形式的3122.55),解释您获得的结果。
通常,%g将始终为您提供最短的结果,这意味着,如果可以缩短表示您的数字的数字序列而又不损失任何精度,则可以这样做。
为了进一步说明该示例,当您使用%.17g且小数点17包含一个与0(特别是2)不同的值时,您最终得到了完整的数字3122.5500000000002

实际上是%.17g为您提供了准确的结果,而%.16g仅为您提供了带误差的四舍五入近似值(与内存中的值进行比较时)。
如果要获得更高的固定精度,请改用%f%F

07-28 03:32