【问题标题】:what can to_string() return in NaN cases在 NaN 情况下 to_string() 可以返回什么
【发布时间】:2014-02-28 02:04:43
【问题描述】:

我正在使用 VS 2012,我遇到了非常恼人的行为(有时我的浮点数是 NaN):

auto dbgHelp = std::to_string(myFloat);

dbgHelp 最终包含 5008 个字符(你不能发明这些东西) 其中大多数为 0, 结果是: 0.#INF00

那么这是一个错误或标准允许像这样愚蠢的返回值吗?

修复是微不足道的,对我来说,用三元运算符和isnan() 手动做正确的事情 但我想知道标准是否对此有具体规定……

【问题讨论】:

  • float 没有 NaN 的值。你的myFloat 的实际价值是多少?
  • 您可以随时追踪到to_string 以更好地了解为什么它可能会像现在这样失败。
  • MSVC 源代码中充斥着宏重定向、TMP 和 dbg 检查... :D
  • 那不是 NaN,它是 Infinity。你可能被零除。该标准没有描述无限有多少个零,<xlocnum> 中的 std::num_put() 函数认为 5000 绰绰有余。该错误已经been filed。它似乎与 std::to_string() 的早期草案有关,之前被 STL 描述为“令人讨厌”。强词夺理。

标签: c++ visual-c++ c++11


【解决方案1】:

std::to_string 重载在 [string.conversions]/7 中指定:

string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);

7返回: 每个函数都返回一个 string 对象,该对象包含其参数值的字符表示形式,该参数值将通过使用格式调用 sprintf(buf, fmt, val) 生成"%d""%u""%ld""%lu""%lld""%llu""%f""%f""%Lf" 的指定符,其中 buf 指定内部字符缓冲区足够大。

sprintf 在 C99(实际上是 N1256)7.19.6.6/2 中有详细说明:

sprintf函数等价于fprintf,只是输出被写入 一个数组(由参数s 指定)而不是流。写入空字符 在所写字符的末尾;它不计为返回值的一部分。如果 复制发生在重叠的对象之间,行为未定义。

fprintf 跳到 7.19.6.1,格式标志在第 8 段中描述。具体而言,对于 f 格式:

表示浮点数的double 参数转换为 [−]ddd.ddd 样式的十进制表示法,其中后面的位数 小数点字符等于精度规范。如果 精度缺失,取6;如果精度为零且 # 标志为 未指定,不出现小数点字符。如果是小数点 字符出现时,其前至少出现一位数字。该值四舍五入为 适当的位数。

代表无穷大的double 参数转换为其中一种样式 [-]inf[-]infinity — 哪种样式是实现定义的。一个 表示 NaN 的双参数转换为其中一种样式 [-]nan[-]nan(n-char-sequence) — 哪种风格,以及含义 任何n-char-sequence,都是实现定义的。 F 转换说明符 生成 INFINFINITYNAN 而不是 infinfinitynan, 分别。

综上所述,当float foo 为正无穷大时,std::to_string(foo) 应返回std::string("inf")

【讨论】:

    猜你喜欢
    • 2012-02-24
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 2020-02-07
    • 2020-11-04
    • 2015-03-06
    相关资源
    最近更新 更多