在 §7.22.1.3 Thestrtod()
和functions中strtof()
,strtold()
C11 标准 (ISO/IEC 9899:2011) 说:
函数返回转换后的值(如果有)。如果无法执行转换,则返回零。如果正确的值溢出并且默认舍入生效(7.12.1),则返回加减HUGE_VAL
、、HUGE_VALF
或HUGE_VALL
(根据值的返回类型和符号),并将宏的值ERANGE
存储在
errno
. 如果结果下溢 (7.12.1),则函数返回一个值,其大小不大于返回类型中的最小归一化正数;是否
errno
获取值ERANGE
是实现定义的。
该标准还在 §5.2.4.2.2浮点类型的特性中指出 IEC 60559 (IEEE 754) 浮点数有限制:
DBL_MIN 2.2250738585072014E-308 // decimal constant
由于 1.8011670033376514e-308 小于DBL_MIN
,因此您会得到一个低于正常值的数字,并且ERANGE
非常合适(但可选)。
在带有 GCC 4.9.1 的 Mac OS X 10.9.4 上,以下程序:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *end;
errno = 0;
double d = strtod("1.8011670033376514e-308", &end);
if (errno != 0)
{
int errnum = errno;
printf("%d: %s\n", errnum, strerror(errnum));
}
printf("%24.16e\n", d);
unsigned char *p = (unsigned char *)&d;
const char *pad = "";
for (size_t i = 0; i < sizeof(double); i++)
{
printf("%s0x%.2X", pad, *p++);
pad = " ";
}
putchar('\n');
return 0;
}
产生输出:
34: Result too large
1.8011670033376514e-308
0x01 0x00 0x00 0x00 0xA8 0xF3 0x0C 0x00
具有讽刺意味的是,错误消息是错误的——值太小——但你不能拥有一切。