【问题标题】:VS2013: strtof doesn't set ERANGE?VS2013:strtof 没有设置 ERANGE?
【发布时间】:2017-01-09 00:18:34
【问题描述】:

在 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() 函数将 double 值设置为 +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?

【问题讨论】:

  • MSVC 2015 在这两种情况下都给出了 errno='Result too large'。必须是已修复的错误。
  • 您可以检查您的strtof 函数是否通过调用strtod 来实现,方法是使用strtof 解析一个字符串,例如"1.01161128282547"。当这个十进制表示被解析为 double 并四舍五入到最接近的 float 时,它产生的结果与直接将字符串解析为 float(“双舍入”)不同。由于这个原因,以这种方式实现的strtof 函数质量很差,即使它正确处理溢出也是如此。质量strtof 产生浮动1.01161134f。一个可怜的strtof 产生1.01161122f
  • @WeatherVane 我会在 VS2015 中尝试,然后标记答案
  • @PascalCuoq 对未来访客的宝贵观察,谢谢!

标签: c string floating-point errno


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-11
    • 2016-05-17
    • 2023-04-03
    • 1970-01-01
    • 2017-08-17
    • 2023-04-09
    • 1970-01-01
    • 2013-12-24
    相关资源
    最近更新 更多