这是一个非常经典且重要的 C 语言知识点,因为它涉及到历史、标准和实际编程实践。

(图片来源网络,侵删)
核心结论先行
在 现代标准 C 语言(C89/C90 及之后) 中,long float 不是有效的类型名,它是一个被保留的关键字,但它的行为等同于 float。
long float float。
详细解释
历史渊源:long float 的由来
long float 这个概念主要源于 C 语言的早期历史,特别是 C89/C90 标准(也称为 ANSI C)之前。
在那个时期,不同的编译器厂商(如早期的 Microsoft C, Borland C, VAX C 等)为了支持当时流行的硬件架构(如 VAX、IBM 大型机等),引入了多种浮点类型,其中就包括 long float。
- 目的:
long float通常是比float精度更高、范围更大的浮点类型,类似于double的角色,在某些系统上,long float甚至可能比double还要大(80 位的扩展精度浮点数)。 - 问题:由于没有统一标准,
long float在不同编译器、不同平台上的实现和行为是不兼容的,这导致了严重的可移植性问题。
标准化与统一
为了解决这种混乱,C89/C90 标准 对 C 语言的类型系统进行了标准化和简化,标准委员会做出了一个关键决定:
- 保留关键字:
long float被保留为关键字,以防旧的代码在新的编译器下出现语法错误。 - 定义行为:标准明确规定,
long floatfloat,编译器遇到long float时,必须将其视为float来处理。
这样做的好处是:
- 向后兼容:旧的、使用
long float的代码在新的标准编译器下依然可以编译通过,只是它的行为会变成float,而不是原来可能的高精度类型。 - 消除歧义:标准用三个明确的浮点类型取代了混乱的局面:
floatdoublelong double
从 C89/C90 开始,long double 成了表示最高精度浮点类型的标准方式,取代了 long float 的历史角色。
现代编程实践
在今天的 C 语言编程中(C99, C11, C17, C23...),你应该遵循以下规则:
| 类型名 | 别名 | 描述 | 大小(典型) | 精度(典型) |
|---|---|---|---|---|
float |
单精度浮点数 | 最基本的浮点类型 | 4 字节 | 约 6-7 位有效数字 |
double |
双精度浮点数 | 默认的浮点类型,精度更高 | 8 字节 | 约 15-16 位有效数字 |
long double |
长双精度浮点数 | 通常精度最高 | 8, 12, 或 16 字节 | 取决于实现,>= double |
long float |
(不推荐) | float 的别名 |
4 字节 | 约 6-7 位有效数字 |
你应该永远使用 float, double, 或 long double。
绝对不要在新的代码中使用 long float,原因如下:
- 可读性差:它会误导其他程序员,让他们误以为这是一种特殊的、高精度的类型。
- 缺乏意义:它没有任何性能或精度上的优势,它就是
float。 - 不符合标准:虽然编译器允许它,但它不属于标准的、推荐的用法。
代码示例
让我们通过代码来验证一下 long float 和 float 的关系。
#include <stdio.h>
#include <float.h> // 用于获取浮点类型的特性
int main() {
// 声明一个 long float 变量
// 注意:虽然编译器允许,但这不是好的做法
long lf_num = 3.14159265359L;
// 声明一个 float 变量
float f_num = 3.14159265359f;
// 声明一个 double 变量
double d_num = 3.14159265359;
// 声明一个 long double 变量
long double ld_num = 3.14159265359L;
// 打印它们的大小(字节)
printf("Size of long float: %zu bytes\n", sizeof(lf_num));
printf("Size of float: %zu bytes\n", sizeof(f_num));
printf("Size of double: %zu bytes\n", sizeof(d_num));
printf("Size of long double: %zu bytes\n\n", sizeof(ld_num));
// 打印它们的精度(DBL_DIG 是 double 的有效数字位数)
// 对于 float, 我们使用 FLT_DIG
printf("Precision of float: %d decimal digits\n", FLT_DIG);
printf("Precision of long float: %d decimal digits\n", FLT_DIG); // long float 的精度和 float 一样
printf("Precision of double: %d decimal digits\n", DBL_DIG);
printf("Precision of long double: %d decimal digits\n", LDBL_DIG);
// 尝试打印值,看看它们的区别
printf("\nValues:\n");
printf("lf_num = %f\n", lf_num);
printf("f_num = %f\n", f_num);
printf("d_num = %f\n", d_num);
printf("ld_num = %Lf\n", ld_num); // 注意 long double 的打印格式是 %Lf
return 0;
}
典型输出(在 x86-64 Linux/macOS 上):
Size of long float: 4 bytes
Size of float: 4 bytes
Size of double: 8 bytes
Size of long double: 16 bytes
Precision of float: 6 decimal digits
Precision of long float: 6 decimal digits
Precision of double: 15 decimal digits
Precision of long double: 18 decimal digits
Values:
lf_num = 3.141593
f_num = 3.141593
d_num = 3.141593
ld_num = 3.141593
从输出中可以清楚地看到:
long float和float的大小(sizeof)完全相同。long float和float的精度(FLT_DIG)完全相同。- 它们的打印值也完全一样。
| 特性 | 描述 |
|---|---|
| 有效性 | 在现代标准 C 中,long float 是一个保留但无效的类型名。 |
| 别名 | long float 是 float 的一个完全等价的别名。 |
| 历史 | 源于 C 标准化前,用于表示高精度浮点数,但缺乏统一性。 |
| 标准 | C89/C90 及之后的标准将其行为定义为等同于 float。 |
| 推荐用法 | 永远不要使用 long float,请使用 float、double 或 long double。 |
| 目的 | 保留它只是为了兼容非常古老的代码,防止编译器报错。 |
记住这个简单的规则:当你在 C 语言中需要浮点数时,请选择 float、double 或 long double,并忘记 long float 的存在。
