该程序在第一个命令行参数上调用 strtod() 并打印返回值:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <float.h>
int main(int argc, char **argv)
{
errno = 0;
double d = strtod(argv[1], NULL);
int errno_sav = errno;
printf("string = %s\n", argv[1]);
printf("d = %.*e = %a\n", DBL_DIG + 2, d, d);
printf("errno = %d\n", errno_sav);
printf("DBL_MIN = %.*e = %a\n", DBL_DIG + 2, DBL_MIN, DBL_MIN);
return 0;
}
当我在 SUSE Linux Enterprise Server 11 SP2 或 Linux Mint 17 Qiana 上运行它时,参数为2.22507385850720138309e-308
,对应于最小的可表示1双精度值 (DBL_MIN),它给出了我期望的输出:
string = 2.22507385850720138309e-308
d = 2.22507385850720138e-308 = 0x1p-1022
errno = 0
DBL_MIN = 2.22507385850720138e-308 = 0x1p-1022
但是,在具有相同参数2的 SUSE Linux Enterprise Server 11 SP3 上,errno 设置为 ERANGE:
string = 2.22507385850720138309e-308
d = 2.22507385850720138e-308 = 0x1p-1022
errno = 34
DBL_MIN = 2.22507385850720138e-308 = 0x1p-1022
第二种行为是否有效,如果是,为什么?
脚注:
由于 DBL_MIN 是可表示的,我认为这个问题与“将 C 字符串转换为 / 从双精度数转换时的奇怪行为”不同,其中转换的值已下溢。
在 SUSE 上,如果我使用参数运行程序,
2.22507385850720138310e-308
则 errno 设置为 0。(如果我使用参数运行程序,0x1p-1022
则 errno 也设置为 0。)