在Visual Studio 2013中,我有以下的测试代码:
这种行为是否预期,还是实现上的细微差别?顺便说一句:在我的看法中,strtof()可能会调用strtod(),在将double转换为float产生+INF结果后没有适当地设置errno?
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( int argc, const char* argv[])
{
static const char* floatStr = "3.40282346638528859811704183485E+39";
static const char* doubleStr = "1.79769313486231570814527423732E+309";
char* end;
float floatVal = 42.0f;
double doubleVal = 42.0;
errno = 0;
floatVal = strtof(floatStr, &end);
printf("Conversion of '%s':\nfloatVal=%f\nerrno='%s'\n",
floatStr,
floatVal,
strerror(errno));
errno = 0;
doubleVal = strtod(doubleStr, &end);
printf("Conversion of '%s':\ndoubleVal=%f\nerrno='%s'\n",
doubleStr,
doubleVal,
strerror(errno));
return 0;
}
本文旨在展示使用strtof()和strtod()函数处理非常大(溢出)输入时观察到的行为。
我发现,strtof()函数会将浮点值设置为+INF,但不会设置ERANGE errno。然而,strtod()函数将双精度值设置为+INF,并设置ERANGE errno:
Conversion of '3.40282346638528859811704183485E+39':
floatVal=1.#INF00
errno='No error'
Conversion of '1.79769313486231570814527423732E+309':
doubleVal=1.#INF00
errno='Result too large'
这种行为是否预期,还是实现上的细微差别?顺便说一句:在我的看法中,strtof()可能会调用strtod(),在将double转换为float产生+INF结果后没有适当地设置errno?
strtof
解析字符串,例如“1.01161128282547”,来检查您的strtof
函数是否是通过调用strtod
实现的。当将此十进制表示形式解析为double
并四舍五入为最接近的float
时,它产生的结果与直接解析为float
的字符串不同(“双重舍入”)。即使正确处理溢出,以这种方式实现的strtof
函数也是质量较差的。优质的strtof
生成浮点数1.01161134f
。而劣质的strtof
则会生成1.01161122f
。 - Pascal Cuoq