假设浮点数或双 NaN 将始终作为字符串"nan"是否安全?

Is it safe to assume that float or double NaNs will always be "nan" as a string?

本文关键字:字符串 nan 是否 安全 浮点数 NaN 假设      更新时间:2023-10-16

如果我通过std::cout打印NaN或将其转换为字符串,标准是否说它必须是"nan"作为字符串?

有没有其他方法可以将 NaN 转换为字符串,但这不是真的?

#include <iostream>
#include <limits>
int main() {    
    float x = std::numeric_limits<float>::quiet_NaN();
    std::cout << x << 'n';                 // Output: nan
    std::cout << std::to_string(x) << 'n'; // Output: nan
    printf("%f", x);                        // Output: nan
    // possibly other variants to print x
}

std::to_string 是根据 std::sprintf 定义的,C++从 C99 标准库中采用。它在那里说:

非数字转换为 nannan(char_sequence) 。使用哪一个是实现定义的。

所以字符串将以 nan 开头,但后面可能还有其他字符。

不幸的是,Microsoft的库似乎不合规。看到这个答案:

https://stackoverflow.com/a/7478290/856199

因此,在考虑了所有这些之后,最终结果是您的 C 标准库不符合 C99,因为根据上述内容,1.#QNAN 不是 fprintf 的有效输出。但是,众所周知,Microsoft的 C 运行时不符合 C99 标准,据我所知,它不打算很快变得合规。


(题外话(
不要使用std::endl,除非你真的想要一个简短的'n' << std::flush形式。

添加到 @Nikos C. :

std::cout 是一个 std::basic_ostream 导致 std::num_put 关于格式,上面写着

如果 v 的类型是浮点类型,则第一个适用的 选择以下选项:

If floatfield == std::ios_base::fixed, will use conversion specifier %f 
If floatfield == std::ios_base::scientific && !uppercase, will use conversion specifier %e 
If floatfield == std::ios_base::scientific, will use conversion specifier %E

所以我要得出结论,std::cout 也与 printf 有关