我正在学习 C 编程语言并正在弄清楚格式说明符,但似乎 double 和 %f 无法正常工作。
这是我的代码
#include <stdio.h>
int main(void)
{
double a = 15.1234567899876;
printf("%13.10f", a);
}
Run Code Online (Sandbox Code Playgroud)
在我的教科书中,“%13.10f”中指出,13 代表我们要打印的总位数(包括点),10 是小数位数。所以我期望得到 15.1234567899 但没有。
运行后我得到 15.1234567900。这不仅仅是小数点不够,而是小数点打印不正确。变量 a 在 7 之后和 9 之前有 8,但打印的数字没有。
有人可以告诉我我错在哪里吗?
谢谢。脂蛋白
printf应该将结果四舍五入到您要求的位数。
you asked: 15.1234567899876
you got: 15.1234567900
digit count: 1234567890
Run Code Online (Sandbox Code Playgroud)
正确的行为也是如此printf。
但您应该注意,类型float和double都有有限的精度。此外,它们的有限精度是二进制位的数量,而不是十进制数字。因此,在 a 大约 7 位数字float和 a 大约 16 位数字之后double,如果您没有意识到发生了什么,您将开始看到看起来很奇怪的结果。如果您开始打印更多数字,您可以看到这一点:
printf("%18.15f\n", a);
you asked: 15.1234567899876
you got: 15.123456789987600
Run Code Online (Sandbox Code Playgroud)
所以没关系。但:
printf("%23.20f\n", a);
you asked: 15.1234567899876
you got: 15.12345678998759979095
Run Code Online (Sandbox Code Playgroud)
在这里我们看到,在第 15 位,内部实际存储的数字开始与您要求的数字略有不同。您可以在浮点数学是否被破坏?中阅读更多相关信息。
脚注:内部实际存储的数字是多少?它是十六进制浮点数,或者用 C 的格式0xf.1f9add3b7744表示, 。转换回十进制,正好是 15.1234567899875997909475699998438358306884765625。所有其他再现(15.1234567900、15.123456789987600 和 15.12345678998759979095)均四舍五入为较小的位数。内部值也许最有意义,以二进制表示,其中 ,具有 53 个有效位,其中 52 个是显式的,1 个是隐式的,符合 IEEE-754 双精度。%a0x1.e3f35ba76ee88p+30b1111.0001111110011010110111010011101101110111010001000