double 是 C 语言中一种用于表示浮点数(即带小数点的数)的数据类型,它的范围和精度由IEEE 754 标准定义,并且其具体数值取决于计算机的字长(通常是 32 位或 64 位)。

(图片来源网络,侵删)
在绝大多数现代计算机系统(包括 Windows, macOS, Linux)和编译器(如 GCC, Clang, MSVC)上,double 类型都遵循 IEEE 754 双精度浮点数标准,它占用 64 位(8 字节) 的内存。
下面我们以最常见的情况——64 位 double 为例,详细说明其范围。
范围详解
一个 64 位的 double 数被划分为三个部分:
| 部分 | 占用位数 | 含义 |
|---|---|---|
| 符号位 | 1 位 | 决定数字是正数还是负数(0为正,1为负) |
| 指数位 | 11 位 | 决定数字的大小数量级(类似于科学计数法中的指数) |
| 尾数位 | 52 位 | 决定数字的精度(类似于科学计数法中的有效数字) |
根据这个划分,double 的数值范围可以表示为:

(图片来源网络,侵删)
±(1 - 2⁻⁵²) × 2¹⁰²³ 到 ±(2 - 2⁻⁵²) × 2⁻¹⁰²²
为了方便理解,我们通常用近似值来表示其范围:
- 正数范围:约
2250738585072025e-308到7976931348623157e+308 - 负数范围:约
-1.7976931348623157e+308到-2.2250738585072025e-308
关键概念解释:
- 最小正数:这是
double能表示的最接近于零的正数,它非常小,约为2250738585072025e-308,任何比这个值更小的正数,如果用double存储,可能会被舍入为零(称为“下溢”到零)。 - 最大正数:这是
double能表示的最大的有限数,它非常大,约为7976931348623157e+308,任何比这个值更大的数,如果用double存储,将会被表示为“无穷大”(INF),称为“上溢”。 - 特殊值:
- 无穷大:当计算结果超出最大正数范围时,会产生
+INF或-INF。 - 非数字:当进行无效的数学运算时(如
0 / 0.0),会产生NaN,它表示一个不是一个数字的值。
- 无穷大:当计算结果超出最大正数范围时,会产生
精度
除了范围,double 的另一个重要特性是精度,也就是它能精确表示多少位有效数字。
double大约能提供 15 到 17 位 的十进制有效数字精度。- 这 52 位的尾数可以精确表示大约 15-17 位十进制数。
举例说明精度:

(图片来源网络,侵删)
#include <stdio.h>
int main() {
double a = 123456789012345.0;
double b = 123456789012345.6789;
printf("a = %.15f\n", a); // 输出 a
printf("b = %.15f\n", b); // 输出 b
// 我们会发现 a 和 b 的输出在小数点后几位是相同的,
// 这是因为 double 无法精确表示 b 的小数部分。
// 它会四舍五入到最接近的可表示值。
if (a == b) {
printf("a and b are considered equal by double.\n");
} else {
printf("a and b are not equal.\n");
}
return 0;
}
可能的输出:
a = 123456789012345.007812500000000
b = 123456789012345.007812500000000
a and b are considered equal by double.
在这个例子中,6789 超出了 double 的精确表示能力,因此被存储为 0078125,与 a 的值在比较时被认为是相等的。
float 与 double 的对比
为了更好地理解 double,我们通常将它与 float 进行比较。
| 特性 | float (单精度) |
double (双精度) |
|---|---|---|
| 占用空间 | 32 位 (4 字节) | 64 位 (8 字节) |
| 符号位 | 1 位 | 1 位 |
| 指数位 | 8 位 | 11 位 |
| 尾数位 | 23 位 | 52 位 |
| 范围 | 约 ±3.4e-38 到 ±3.4e+38 |
约 ±2.2e-308 到 ±1.8e+308 |
| 精度 | 约 6-9 位十进制有效数字 | 约 15-17 位十进制有效数字 |
double 的范围比 float 大得多,精度也高得多,在绝大多数需要浮点数计算的场景下,都推荐使用 double,因为它能避免更多的精度丢失和溢出问题。float 主要用于对内存有极其严格要求的嵌入式系统或图形编程中。
如何在代码中查看范围?
C 标准库 <float.h> 中定义了与浮点数相关的宏,可以让你在编译时或运行时获取这些精确值。
#include <stdio.h>
#include <float.h> // 必须包含此头文件
int main() {
printf("double 类型信息:\n");
printf("-----------------\n");
printf("存储大小: %zu 字节\n", sizeof(double));
printf("最小正数: %e\n", DBL_MIN);
printf("最大正数: %e\n", DBL_MAX);
printf("精度 (小数点后位数): %d\n", DBL_DIG);
printf("指数范围 (最小): %d\n", DBL_MIN_EXP);
printf("指数范围 (最大): %d\n", DBL_MAX_EXP);
return 0;
}
在 64 位系统上的典型输出:
double 类型信息:
-----------------
存储大小: 8 字节
最小正数: 2.225074e-308
最大正数: 1.797693e+308
精度 (小数点后位数): 15
指数范围 (最小): -1021
指数范围 (最大): 1024
| 特性 | 描述 |
|---|---|
| 类型 | 双精度浮点数 |
| 标准 | IEEE 754 |
| 大小 | 64 位 (8 字节) - 在绝大多数现代系统上 |
| 范围 | 约 ±2.2e-308 到 ±1.8e+308 |
| 精度 | 约 15-17 位十进制有效数字 |
| 何时使用 | 默认选择,当需要进行科学计算、金融计算或任何对精度要求较高的浮点运算时,应使用 double。 |
