Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C strtod下溢,返回值!=0_C_Strtod - Fatal编程技术网

C strtod下溢,返回值!=0

C strtod下溢,返回值!=0,c,strtod,C,Strtod,以下是我的测试代码: errno = 0; d = strtod("1.8011670033376514e-308", NULL); 使用此代码,我得到d==1.8011670033376514e-308和errno==ERANGE 来自斯特罗德(3): 如果正确的值会导致溢出,则返回加号或减号巨值(巨值,巨值)(根据值的符号),并且ERANGE存储在errno中。如果正确的值会导致下溢,则返回零,并将ERANGE存储在errno中 因此,在我看来,errno应该是零(无错误),或者d应该是零

以下是我的测试代码:

errno = 0;
d = strtod("1.8011670033376514e-308", NULL);
使用此代码,我得到
d==1.8011670033376514e-308
errno==ERANGE

来自斯特罗德(3):

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

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

这是一个错误,还是我遗漏了什么?许多不同版本的eglibc和gcc都会出现这种情况。

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

请参阅手册页以了解:

头文件定义整数变量
errno
,该变量 在发生错误时,由系统调用和某些库函数设置 错误以指示出错的地方。它的价值只有一个 当调用的返回值指示错误时(即,
-1
) 大多数系统调用;
-1
NULL
来自大多数库函数)a 允许成功的函数更改
errno

因此,如果函数的返回值实际返回一个指示发生错误的值,则只能检查
errno

关于
errno
(以及它与
strtod()
)的关系的更完整的解释可以找到。

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

函数返回转换后的值(如果有)。如果无法执行转换, 返回零。如果正确值溢出且默认舍入生效(7.12.1), 返回正负
巨值
巨值
,或
巨值
(根据 返回值的类型和符号),宏
ERANGE
的值存储在
errno
。如果结果下溢(7.12.1),函数返回一个数值,其大小为 不大于返回类型中的最小规范化正数;是否
errno
获取实现定义的值
erage

本标准还在§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;
}

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

代码的运行方式如下:

如果正确的值会导致下溢,则应返回其大小不大于返回类型中最小标准化正数的值,并将errno设置为[ERANGE]

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

#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