在printf中,双精度浮点数的正确格式说明符

23 浏览
0 Comments

在printf中,双精度浮点数的正确格式说明符

在printf中double的正确格式说明符是什么?是%f还是%lf?我认为应该是%f,但我不确定。

代码示例

#include 
int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}

admin 更改状态以发布 2023年5月23日
0
0 Comments

鉴于 C99 标准(即 N1256 草案),规则取决于函数类型:fprintf(printf,sprintf,...)或 scanf。

以下是相关部分的摘录:

前言

本版的出版取消并替代了第一版 ISO/IEC 9899:1990,该版由 ISO/IEC 9899/COR1:1994、ISO/IEC 9899/AMD1:1995 和 ISO/IEC 9899/COR2:1996 进行修改和更正。

相对于上一版,主要的变化包括:

  • 允许在 printf 中使用 %lf 转换说明符

7.19.6.1 函数 fprintf

7 长度限定符及其含义如下:

l(小写 L) 表示(...)对后续的 a、A、e、E、f、F、g 或 G 转换说明符没有影响。

L 表示后续的 a、A、e、E、f、F、g 或 G 转换说明符应用于 long double 类型的参数。

相同的规则适用于 printf、sprintf 等函数。

7.19.6.2 函数 fscanf

11 长度限定符及其含义如下:

l(小写 L)表示(...)后续的 a、A、e、E、f、F、g 或 G 转换说明符应用于指向 double 的指针类型参数;

L 表示后续的 a、A、e、E、f、F、g 或 G 转换说明符应用于指向 long double 的指针类型参数。

12 转换说明符及其含义如下:

a、e、f、g 匹配可选符号的浮点数(...)

14 转换说明符A、E、F、G和X也有效,并与相应的小写字母说明符a、e、f、g和x行为相同。

简而言之,对于fprintf,指定了以下说明符和相应的类型:

  • %f -> 双精度浮点数(double)
  • %Lf -> 长双精度浮点数(long double)。

对于fscanf,它是:

  • %f -> 单精度浮点数(float)
  • %lf -> 双精度浮点数(double)
  • %Lf -> 长双精度浮点数(long double)。
0
0 Comments

""%f"" 是一个(或至少一个)正确的双精度浮点数格式。不存在一个用于 float 的格式,因为如果您尝试将一个 float 传递给 printf,则在 printf 接收它之前,它将被提升为 double"%lf" 在当前标准下也是可以接受的,l 指定在 f 转换说明符之后没有任何效果(其中包括其他转换说明符)。

需要注意的是,在这一点上,printf 格式字符串与 scanf (以及 fscanf 等)格式字符串大不相同。对于输出,您正在传输一个值,当作为可变参数传递时,它会从 float 提升为 double。对于输入,您正在传递一个指针,该指针不会提升,因此您必须告诉 scanf 您想要读取一个 float 还是 double,因此对于 scanf%f 意味着您想要读取一个 float,而 %lf 表示您想要读取一个 double(对于 long double,您无论是使用 printf 还是 scanf,都需要使用 %Lf)。


1. C99,§6.5.2.2/6:“如果表示被调用函数的表达式的类型不包括原型,则在每个参数上执行整数提升,并将类型为float的参数提升为double。这些被称为默认参数升级。”在C++中措辞略有不同(例如,它不使用“原型”一词),但效果相同:在它们被函数接收之前,所有可变参数都要经过默认提升。

0