是否可以安全地假设float或double NaN始终作为字符串“ nan”?

时间:2019-06-18 10:00:22

标签: c++ floating-point nan

如果我通过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
}

2 个答案:

答案 0 :(得分:2)

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

  

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

因此该字符串将以nan开头,但是后面可能还有其他字符。

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

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

  

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


(离题)
除非您确实想要简短的std::endl形式,否则不要使用'\n' << std::flush

答案 1 :(得分:1)

添加到@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相关联