我无法理解 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;
}
当我编译并运行这个程序(在带有 gcc 4.5.2 的 Core 2 Duo 上)时得到的输出是:
DBL_MIN = 2.225074e-308, x = 2.225074e-310
Error converting '1e-310': Numerical result out of range
y = 1.000000e-310
我的问题是:
- 为什么 x 打印为非零数字?我知道编译器有时出于计算目的将双精度类型提升为更高精度的类型,但是 printf 不应该将 x 视为 64 位双精度类型吗?
- 如果 C 库秘密使用扩展精度浮点数,为什么 strtod 在尝试转换这些小数字时设置 errno?为什么它会产生正确的结果呢?
- 这种行为只是一个错误,是我的特定硬件和开发环境的结果吗? (不幸的是,我目前无法在其他平台上进行测试。)
谢谢你提供的所有帮助。当我收到反馈时,我会尽力澄清这个问题。
因为存在非正规数 http://en.wikipedia.org/wiki/Denormal_numbers在 IEEE-754 标准中。DBL_MIN
是最小的归一化 value.
-
因为标准是这么说的(C99 7.20.1.3):
如果
结果下溢(7.12.1),函数返回一个大小不大于的值
比返回类型中最小的标准化正数; errno 是否获取
值 ERANGE 是实现定义的。
返回“正确”值(即 1e-310)遵循上述约束。
所以不是一个错误。这在技术上依赖于平台,因为 C 标准对非正规数 (AFAIK) 的存在或行为没有提出要求。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)