VS2013:strtof不设置ERANGE?

4
在Visual Studio 2013中,我有以下的测试代码:
#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?

1
MSVC 2015在两种情况下都会出现“errno ='Result too large'”错误。必须修复此漏洞。 - Weather Vane
2
您可以通过使用strtof解析字符串,例如“1.01161128282547”,来检查您的strtof函数是否是通过调用strtod实现的。当将此十进制表示形式解析为double并四舍五入为最接近的float时,它产生的结果与直接解析为float的字符串不同(“双重舍入”)。即使正确处理溢出,以这种方式实现的strtof函数也是质量较差的。优质的strtof生成浮点数1.01161134f。而劣质的strtof则会生成1.01161122f - Pascal Cuoq
@WeatherVane 我会尝试在VS2015中完成,然后标记一个答案。 - Squirrel
@PascalCuoq 对于未来的访问者来说是非常有价值的观察,谢谢! - Squirrel
1个回答

3

正如WeatherVane指出的那样,这在VS2015中不会发生,并且似乎是VS2013实现中的一个错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接