在C++中,LONG float和double有什么区别?

6
我知道浮点数和双精度浮点数的精度有很大差别。我明白这一点。但是,在C++中,调用scanf和printf函数时,指定双精度浮点数的符号是“%lf”,这代表长浮点数,对吗?因此,虽然浮点数比双精度浮点数精度低,但是一个“长”浮点数(可能被称为长浮点数,因为它可以通过具有更多项来变得“更长”)具有相同的准确性,因此本质上是相同的东西?
仅为澄清,以下是我的意思:
double number = 3.14159;
printf("The number is %lf", number);

因此,我的问题的核心是:长浮点数是否是double的另一个名称?

4
没有所谓的“long float”,编译器会报错。从概念上讲,你可以称之为“长浮点数”,这并不是错误的。 - milleniumbug
1
我没有将其定义为长浮点数。对于造成的混淆,我感到抱歉。我已经编辑了帖子以澄清。 - Nealon
1
@milleniumbug,但可能会有长双精度:http://msdn.microsoft.com/zh-cn/library/cc953fe1.aspx - Mark Ransom
4个回答

19

据我所知,long float 并非一种数据类型。

这篇文章为您提供了有关为什么人们在使用 printf 打印 double时要使用 lf 的信息,如果这是您困惑的原因。

感谢 @Jerry Coffin:

"%f" 是打印 double 类型的(或至少是其中之一)正确格式。没有 float 类型的格式,因为如果你尝试将 float 传递给 printf,它将在传递给 printf 之前被提升为 double。 "%lf" 在当前标准下也是可接受的 -- 如果后面跟着 f 转换说明符,则规定 l 不产生作用 (还有其他一些说明符)。

所以当人们执行以下操作时:

 printf("The number is %lf", number);

做以下操作是等价的:

printf("The number is %f", number); //l has no effect when printing double

我在扫描双精度浮点数时使用%lf,而且它有效。根据下面@milleniumbug的说法,%f不行。那么按照这个推理,%lf不就是适用于双精度浮点数的“正确”格式吗? - Nealon
1
@Nealon 如果有任何疑惑,我认为这篇文章应该能够解决:https://dev59.com/hXVC5IYBdhLWcg3wsTbv - taocp

5

printf中的占位符名称与类型名称没有任何关联。

它们只是以这种方式命名,以便缩短名称并易于记忆。

浮点型 -> 双精度型 -> 长双精度型

%f -> %lf -> %Lf

(此外,不能将printf的双精度型占位符命名为%d,因为该名称已经保留用于表示int的十进制数(相对于八进制%o))

@taocp的答案解释了为什么您可以在printf中使用%f%lf,但请注意,您无法在scanf中使用它们。


这很有道理。但是选择%lf的原因是什么呢?显然它不是随意选出的一对字母,所以它代表“长浮点数”,对吗?再次强调,我知道“长浮点数”不是一种类型。 - Nealon
1
@Nealon,有很多输入/显示格式需要用只有26个字母的编码方式进行编码,因此在scanf()中选择了%lf来指定读取double,因为f已经表示float,而l则是一个可选字母,用于表示“更大”。如果你愿意,可以把它看作“long float”,但如果你不想让人们笑话,就不要公开这么称呼它。 - Pascal Cuoq
@PascalCuoq,所以l代表长的意思?那真的是我需要知道的全部。我在学习C++时被告知l代表长。 - Nealon
1
@Nealon l 是“长度”字符之一:http://en.wikipedia.org/wiki/Printf_format_string#Format_placeholders。请注意,此页面是用于打印的。格式与扫描格式在有意义的情况下相符,但正如您已经知道的那样,存在细微差别,包括 %f 通常用于打印 double - Pascal Cuoq

4
long float是存在于K&R C第一版中的类型,与double同义。在第一个标准C89 / C90之后,long float被移除,但没有被弃用。C89 / C90也是K&R C第二版。然后有一个名为C94 / C95的多语言修订,添加了wchar_t,以及诸如<iso646.h>之类的功能。 K&R C第一版的许多功能已被弃用,但直到第二个标准C99才被移除。自动返回类型int被删除,C99从默认参数类型int和double中删除。C99标准需要函数原型,而不是函数声明,即int function_declaration(); vs int function_prototype(void);。它还删除了K&R C风格的原型。
// implicit int type
main(argc, argv)
char ** argv;

// explicit int type
int main(argc, argv)
int argc;
char ** argv;

C++比C标准化早得多。模板在1983年被标准化,这使得编译成C代码更加困难。它直到1998年才被标准化。旧的编译器可能已经弃用了一些旧特性,这些特性在更现代的编译器中被删除。 %lf 是一个遗留问题,来自于C标准库中的 long float


0
对于scanf,您需要传递一个指向结果存储位置的指针;使用%f读取float值,使用%lf读取double值;您必须区分它们,因为floatdouble不一定具有相同的表示形式。对于printf,您需要传入要显示的值,并且float值会被提升为double,因为它们作为原型的...部分中的参数传递;也就是说,对于printffloatdouble之间没有区别,所以%f%lf的作用相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接