long double赋值异常:直接写最大常量报错,用LDBL_MAX却正常?
为什么直接写long double范围的常量会触发溢出警告,用LDBL_MAX却正常?
现象复现
代码1:查看long double的取值范围
// 列出long double的范围 #include <stdio.h> #include <float.h> int main() { printf("Long double: %Lg - %Lg\n", LDBL_MIN, LDBL_MAX); }
编译运行后输出:
Long double: 3.3621e-4932 - 1.18973e+4932
代码2:直接使用数值常量赋值给long double
#include <stdio.h> #include <float.h> int main() { long double ld = 1.18973e+4932; printf("Longest double: %Lg", ld); }
执行编译命令:
gcc -std=gnu99 -o fj -Wall -Wno-format-overflow -g r2.c -lm
编译器抛出警告:
r2.c:4:3: warning: floating constant exceeds range of ‘double’ [-Woverflow] 4 | long double ld = 1.18973e+4932; | ^~~~
代码3:使用LDBL_MAX赋值给long double
#include <stdio.h> #include <float.h> int main() { long double ld = LDBL_MAX; printf("Longest double: %Lg\n", ld); }
代码可正常编译运行,输出:
Longest double: 1.18973e+4932
问题
既然1.18973e+4932是long double类型的上限值,为什么直接写这个常量会触发溢出警告,而使用LDBL_MAX却能正常编译?
原因解析
- C语言规定,不带后缀的浮点常量默认是double类型。
1.18973e+4932这个值远大于double类型的最大值(通常约为1.79769e+308),所以编译器在处理这个常量时,会先将其当作double类型解析,发现超出范围后就抛出溢出警告。 - 即便后续将这个溢出的double值赋值给long double变量,常量本身的类型推导早于赋值操作完成,因此警告无法避免。
- 而
LDBL_MAX是<float.h>头文件中定义的long double类型宏常量,它的类型本身就是long double,完全匹配long double的取值范围,所以不会触发溢出警告,编译流程正常。
解决办法
如果要直接定义long double类型的浮点常量,需要给常量加上L后缀,明确指定其类型为long double,示例代码如下:
long double ld = 1.18973e+4932L;
这样编译器会直接将该常量当作long double类型处理,不会再抛出double溢出的警告。
内容的提问来源于stack exchange,提问作者Boffin
相关产品推荐
相关产品推荐

