首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >逆流,返回值!= 0

逆流,返回值!= 0
EN

Stack Overflow用户
提问于 2014-08-26 05:54:35
回答 3查看 1.4K关注 0票数 12

这是我的测试代码:

代码语言:javascript
复制
errno = 0;
d = strtod("1.8011670033376514e-308", NULL);

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

来自strtod(3):

如果正确的值会导致溢出,则返回正负HUGE_VAL (HUGE_VALFHUGE_VALL) (根据值的符号),ERANGE存储在errno中。如果正确的值会导致下溢,则返回零并将ERANGE存储在errno中。

所以,在我看来,要么errno应该是零(没有错误),要么d应该是零(下流量)。

这是个窃听器还是我漏掉了什么?这种情况发生在许多不同版本的eglibc和gcc身上。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-26 06:28:33

在第7.22.1.3节“strtod()__、strtof()strtold()函数”中,C11标准(ISO/IEC 9899:2011)规定:

函数返回转换后的值(如果有的话)。如果不能执行转换,则返回零。如果正确的值溢出和默认舍入有效(7.12.1),则返回正负HUGE_VALHUGE_VALFHUGE_VALL (根据值的返回类型和符号),并将宏ERANGE的值存储在errno中。如果结果下垂(7.12.1),则函数返回一个值,其大小不大于返回类型中最小的归一化正数;errno是否获得ERANGE值是实现定义的。

该标准还在第5.2.4.2.2节中指出,IEC 60559 (IEEE 754)浮点数有以下限制:

DBL_MIN 2.2250738585072014E-308 //十进制常数

因为1.8011670033376514e-308比DBL_MIN小,所以得到一个低于正常值的数字,而ERANGE是非常合适的(但可选)。

在Mac 10.9.4和GCC 4.9.1上,程序如下:

代码语言:javascript
复制
#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;
}

产生的输出:

代码语言:javascript
复制
34: Result too large
 1.8011670033376514e-308
0x01 0x00 0x00 0x00 0xA8 0xF3 0x0C 0x00

具有讽刺意味的是,错误信息是错误的--其值太小--但您不可能拥有所有的东西。

票数 9
EN

Stack Overflow用户

发布于 2014-08-26 06:11:38

如果strtod()返回一个非零值(即非+/- HUGE_VAL),则调用已成功(根据您引用的手册页)。

引用errno.h的手册页

<errno.h>头文件定义了整数变量errno,该变量由系统调用和一些库函数在发生错误时设置,以指示出了什么问题。只有当调用的返回值指示错误(即大多数系统调用的-1;大多数库函数的-1NULL );允许成功的函数更改时,它的值才有意义。

因此,只有当函数的返回值实际返回一个指示发生错误的值时,才能检查errno是否存在错误。

errno的更完整的解释(以及它与strtod()的关系的解释)可以找到on another StackExchange

票数 3
EN

Stack Overflow用户

发布于 2014-08-26 06:30:19

根据strtod(),代码的行为是正确的

如果正确的值会导致下溢,则返回值的大小不大于返回类型中最小的归一化正数,并将errno设置为ERANGE。

我想说的是,您所看到的是Linux手册中的一个详细错误。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25498987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档