我无法理解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
我的问题是:
感谢您提供任何帮助。我会在收到反馈时尝试澄清问题。
答案 0 :(得分:8)
由于IEEE-754标准中存在denormal numbers。 DBL_MIN
是最小的规范化值。
因为标准是这样说的(C99 7.20.1.3):
如果 结果下溢(7.12.1),函数返回一个幅度不大的值 比返回类型中最小的归一化正数;是否errno获得 值ERANGE是实现定义的。
返回“正确”值(即1e-310)遵守上述约束条件。
所以不是错误。这在技术上依赖于平台,因为C标准对非正规数字的存在或行为(AFAIK)没有要求。
答案 1 :(得分:7)
以下是strtod
下溢(C99,7.20.1.3p10)的标准说明
“如果结果下溢(7.12.1),则函数返回一个值,其大小不大于返回类型中的最小标准化正数; errno是否获取值ERANGE是实现定义的。”
关于ERANGE
下溢的strtod
,这是glibc所说的
“当发生下溢时,将引发下溢异常,并返回零(适当签名).errno可能设置为ERANGE,但不保证这一点。”
http://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Math-Error-Reporting.html
(请注意,此页面明确链接到glibc strtod
页面“Parsing of Floats”:
http://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Parsing-of-Floats.html