C++ says almost nothing about the representation of floating point types.
[basic.fundamental]/8
says (Emphasis mine):
There are three floating point types: float
, double
, and long double
. The type double
provides at least as much precision as float
, and the type long double
provides at least as much precision as double. The set of values of the type float
is a subset of the set of values of the type double
; the set of values of the type double
is a subset of the set of values of the type long double
. The value representation of floating-point types is implementation-defined. Integral and floating types are collectively called arithmetic types. Specializations of the standard template std::numeric_limits
(18.3) shall specify the maximum and minimum values of each arithmetic type for an implementation.
If you just write C++ code using float
, double
and long double
, you have virtually no guarantees, apart from those given in the documentation for your particular compiler, and those that can be implied from std::numeric_limits
.
On the other hand, IEEE 754 provides exact definitions of the behaviour and binary representation of its floating point types. These definitions are not quite enough to guarantee identical behaviour on all IEEE 754 platforms, since (for example) IEEE 754 sometimes allows multiple operations to be folded together when the result would be more precise than performing the two operations separately. This is likely to be unimportant to your specific case, since you just want the files to be portable, and probably do not care quite as much about identical queries creating identical changes to the files on different platforms as you do about identical files being loaded in identical ways on different platforms.
So the question is: "how do I get a portable IEEE 754 implementation for C++?".
The answer to this question is somewhat tricky. Most C++ compilers for reasonable platforms will provide at least float
and double
that approximately match IEEE 754's binary32
and binary64
specifications (although you will need to read the documentation for each individual compiler to be sure).
Alternatively, you can use a software floating point implementation or wrapper such as FLIP, libgcc's soft-float, SoftFloat, or STREFLOP. These libraries sometimes still make assumptions about the implementation that are not completely portable according to the C++ standard, so use at your own risk.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…