Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.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字符串转换为双精度或从双精度转换时的奇怪行为_C_Printf_Ieee 754_Strtod - Fatal编程技术网

将C字符串转换为双精度或从双精度转换时的奇怪行为

将C字符串转换为双精度或从双精度转换时的奇怪行为,c,printf,ieee-754,strtod,C,Printf,Ieee 754,Strtod,我很难理解C的规则,当打印双精度或将字符串转换为双精度时,应该假设什么样的精度。以下程序应说明我的观点: #include <errno.h> #include <float.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char **argv) { double x, y; const char *s

我很难理解C的规则,当打印双精度或将字符串转换为双精度时,应该假设什么样的精度。以下程序应说明我的观点:

#include <errno.h>
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {
    double x, y;
    const char *s = "1e-310";

    /* Should print zero */
    x = DBL_MIN/100.;
    printf("DBL_MIN = %e, x = %e\n", DBL_MIN, x);

    /* Trying to read in floating point number smaller than DBL_MIN gives an error */
    y = strtod(s, NULL);
    if(errno != 0)
        printf("  Error converting '%s': %s\n", s, strerror(errno));
    printf("y = %e\n", y);

    return 0;
}
我的问题是:

  • 为什么x打印为非零数字?我知道编译器有时为了计算的目的会将double提升为更高精度的类型,但printf不应该将x视为64位double吗
  • 如果C库秘密使用扩展精度浮点数,为什么在转换这些小数字时,strod会设置errno?为什么它会产生正确的结果呢
  • 这种行为只是一个bug,是我特定的硬件和开发环境造成的吗?(不幸的是,我目前无法在其他平台上进行测试。)
  • 谢谢你能给我的帮助。当我得到反馈时,我会尽力澄清这个问题

  • 因为IEEE-754标准中存在
    DBL_MIN
    是最小的标准化值

  • 因为标准是这么说的(C99 7.20.1.3):

    如果 结果为下溢(7.12.1),函数返回一个大小不大于的值 大于返回类型中的最小规范化正数;厄尔诺是否获得 值ERANGE由实现定义

    返回“正确”值(即1e-310)符合上述约束

  • 所以不是虫子。这在技术上取决于平台,因为C标准对非规范数(AFAIK)的存在或行为没有任何要求


  • 以下是标准对strtod下溢(C99,7.20.1.3p10)的说明

    如果结果下溢(7.12.1),函数返回一个值,其大小不大于返回类型中最小的标准化正数;errno是否获取值ERANGE由实现定义

    关于
    strtod
    underflow上的
    ERANGE
    ,glibc是这么说的

    发生下溢时,会引发下溢异常,并返回零(正确签名)。errno可以设置为ERANGE,但这不能保证

    (请注意,此页面在glibc
    strtod
    页面“浮动解析”上显式链接:

    首先:
    DBL_MIN=2.225074e-308
    没有多大意义,因为最小IEEE DP值是
    4.94066e-324
    。这解释了为什么除以
    100
    仍然正确。但问题是为什么
    DBL_MIN
    不是
    4.94066e-324
    。下面澄清:DBL_MIN是最小的标准化值。谢谢,这是非常有用的信息。我有点希望strod在这种情况下不会标记错误,但我可以看到其原理。我会解决它。
    DBL_MIN = 2.225074e-308, x = 2.225074e-310
      Error converting '1e-310': Numerical result out of range
    y = 1.000000e-310