我在理解C语言中关于打印双精度浮点数时应该采用什么精度,或者将字符串转换为双精度浮点数时遇到了困难。下面的程序可以说明我的问题:
#include <errno.h>
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
double x, y;
const char *s = "1e-310";
/* Should print zero */
x = DBL_MIN/100.;
printf("DBL_MIN = %e, x = %e\n", DBL_MIN, x);
/* Trying to read in floating point number smaller than DBL_MIN gives an error */
y = strtod(s, NULL);
if(errno != 0)
printf(" Error converting '%s': %s\n", s, strerror(errno));
printf("y = %e\n", y);
return 0;
}
我在Core 2 Duo上使用gcc 4.5.2编译并运行此程序时得到的输出结果如下:
DBL_MIN = 2.225074e-308, x = 2.225074e-310
Error converting '1e-310': Numerical result out of range
y = 1.000000e-310
我的问题是:
- 为什么x被打印成非零数?我知道编译器有时会将double类型提升到更高精度的类型进行计算,但printf不应该将x视为64位double吗?
- 如果C库秘密使用扩展精度浮点数,为什么在尝试转换这些小数时strtod会设置errno?为什么它还会产生正确的结果?
- 这种行为只是一个错误,是由于我的特定硬件和开发环境造成的吗?(不幸的是,我目前无法在其他平台上进行测试。)
感谢您能给予的任何帮助。我会在得到反馈后尽力澄清问题。
DBL_MIN = 2.225074e-308
并没有太多意义,因为 IEEE DP 的最小值是4.94066e-324
。这就解释了为什么除以100
仍然可以正确运行。但问题是为什么DBL_MIN
不是4.94066e-324
。 - Mysticial