C++标准没有讨论float和double类型的底层布局,只讨论它们应该表示的值的范围.(对于签名类型也是如此,这是两个恭维还是别的)
我的问题是:用于以可移植方式序列化/反序列化POD类型(如double和float)的技术是什么?目前,似乎唯一的方法是将值表示为字面意义(如"123.456"),double的ieee754布局在所有体系结构上都不是标准的.
我想使用iostream和Visual C++从/向文本文件中读取和写入NaN值.当写NaN值时,我得到1.#QNAN.但是,读回来输出1.0.
float nan = std::numeric_limits<float>::quiet_NaN ();
std::ofstream os("output.txt");
os << nan ;
os.close();
Run Code Online (Sandbox Code Playgroud)
输出是1.#QNAN.
std::ifstream is("output.txt");
is >> nan ;
is.close();
Run Code Online (Sandbox Code Playgroud)
nan等于1.0.
解
最后,正如awoodland所建议的那样,我想出了这个解决方案.我选择"nan"作为NaN的字符串表示.<<和>>运算符都被覆盖.
using namespace ::std;
class NaNStream
{
public:
NaNStream(ostream& _out, istream& _in):out(_out), in(_in){}
template<typename T>
const NaNStream& operator<<(const T& v) const {out << v;return *this;}
template<typename T>
const NaNStream& operator>>(T& v) const {in >> v;return *this;}
protected:
ostream& out;
istream& in;
};
// override << operator for …Run Code Online (Sandbox Code Playgroud) 编译器:来自Nuwen发行版的64位MinGW G ++ 4.9.1,在Windows 8.1下.
码:
#ifdef INCLUDE_IOSTREAM
# include <iostream>
#endif
#include <stdio.h> // ::snprintf
#include <stdlib.h> // EXIT_SUCCESS, EXIT_FAILURE
#include <stdexcept> // std::exception
#ifdef snprintf
# error snprintf defined as macro
#endif
#ifdef _MSC_VER
auto const snprintf = _snprintf;
#endif
void test( double const value, int const precision)
{
char buffer[34];
snprintf( buffer, sizeof( buffer ), "%.*a", precision, value );
printf( "Hex of %.3f with %2d digits: %s\n", value, precision, buffer );
}
auto main() -> int
{ …Run Code Online (Sandbox Code Playgroud) c++ ×3
compiler-bug ×1
double ×1
g++ ×1
hex ×1
ieee-754 ×1
iostream ×1
portability ×1
printf ×1
visual-c++ ×1