将C字符串与double转换时的奇怪行为 [英] Odd behavior when converting C strings to/from doubles

查看:263
本文介绍了将C字符串与double转换时的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解C的规则,即打印双精度或将字符串转换为双精度时应采用的精度.下面的程序应该说明我的观点:

I'm having trouble understanding C's rules for what precision to assume when printing doubles, or when converting strings to doubles. The following program should illustrate my point:

#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;
}

当我编译并运行该程序时(在带有gcc 4.5.2的Core 2 Duo上),我得到的输出是:

The output I get when I compile and run this program (on a Core 2 Duo with gcc 4.5.2) is:

DBL_MIN = 2.225074e-308, x = 2.225074e-310
  Error converting '1e-310': Numerical result out of range
y = 1.000000e-310

我的问题是:

  1. 为什么x被打印为非零数字?我知道编译器有时会出于计算目的而将double提升为精度更高的类型,但是printf不应将x视为64位double吗?
  2. 如果C库秘密使用扩展精度浮点数,为什么在尝试转换这些小数时strtod设置errno?为何它仍然会产生正确的结果?
  3. 此行为是否是我的特定硬件和开发环境所导致的错误? (很遗憾,目前我无法在其他平台上进行测试.)

感谢您提供的任何帮助.得到反馈后,我将尽力澄清问题.

Thanks for any help you can give. I will try to clarify the issue as I get feedback.

推荐答案

  1. 由于存在 反常数 IEEE-754标准. DBL_MIN是最小的归一化值.

因为该标准如此规定(C99 7.20.1.3):

Because the standard says so (C99 7.20.1.3):

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

If the result underflows (7.12.1), the functions return a value whose magnitude is no greater than the smallest normalized positive number in the return type; whether errno acquires the value ERANGE is implementation-defined.

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

Returning the "correct" value (i.e. 1e-310) obeys the above constraint.

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

So not a bug. This is technically platform-dependent, because the C standard(s) place no requirements on the existence or behaviour of denormal numbers (AFAIK).

这篇关于将C字符串与double转换时的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆