这是我的测试代码:

errno = 0;
d = strtod("1.8011670033376514e-308", NULL);

有了这段代码,我得到d == 1.8011670033376514e-308errno == ERANGE

从strtod(3):



因此,在我看来,errno应该为零(无错误)或d应该为零(下溢)。

这是一个错误,还是我缺少了什么?对于eglibc和gcc的许多不同版本,都会发生这种情况。

最佳答案

在§7.22.1.3strtod()strtof()strtold()函数中,C11标准(ISO/IEC 9899:2011)指出:



该标准还在§5.2.4.2.2浮点类型的特性中指出,IEC 60559(IEEE 754)浮点数具有以下限制:



由于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

具有讽刺意味的是,该错误消息是错误的-值太小-但您不能拥有所有内容。

关于c - strtod下溢,返回值!= 0,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25498987/

10-12 19:58