I'm working on a cross-platform app for Windows and Mac OS X, and I have a problem with two standard C library functions:
strtod()
- string-to-double conversionsprintf()
- when used for outputting double-precision floating point numbers)
Their GCC and MSVC versions return different results, in some digits of mantissa. But it plays a cruicial role if the exponent value is large. An example:
MSVC: 9,999999999999999500000000000000e+032
GCC: 9,999999999999999455752309870428e+32
MSVC: 9,999999999999999500000000000000e+033
GCC: 9,999999999999999455752309870428e+33
MSVC: 9,999999999999999700000000000000e+034
GCC: 9,999999999999999686336610791798e+34
The input test numbers have an identical binary representation under MSVC and GCC.
I'm looking for a well-tested cross-platform open-source implementation of those functions, or just for a pair of functions that would correctly and consistently convert double to string and back.
I've already tried the clib GCC implementation, but the code is too long and too dependent on other source files, so I expect the adaptation to be difficult.
What implementations of string-to-double and double-to-string functions would you recommend?
Converting between floating point numbers and strings is hard - very hard. There are numerous papers on the subject, including:
The last of those is a treasure trove of information on floating point decimal arithmetic.
The GNU glibc implementation is likely to be about as good as it gets - but it won't be short or simple.
Addressing examples
A double normally stores 16 (some might argue 17) significant decimal digits. MSVC is processing 17 digits. Anything beyond that is noise. GCC is doing as you ask it, but there aren't enough bits in a double to warrant the extra 14 digits you are requesting. If you had 16-byte '
long double
' values (SPARC, PPC, Intel x86_64 for Mac), then you might warrant 32 significant figures. However, the differences you are showing are QoI; I might even argue that MS is doing a better job than GCC/glibc here (and I don't often say that!).The only algorithm I know for printing the exact value of a floating point number in decimal is as follows:
It's slow and ugly but it works...
The following function
dtoa
returns a string that losslessly converts back into the samedouble
.If you rewrite
aisd
to test all of yourstring
-to-float
implementations, you'll have portable output among them.See Can't get a NaN from the MSVCRT strtod/sscanf/atof functions for the MSVCRT
NaN
problem. If you don't need to recognizeNaN
s, you can output infinity ("1e999"
) when you get one.