Genaue Fließkomma <-> Zeichenkettenkonvertierung
Ich suche nach einer Bibliotheksfunktion, um Gleitkommazahlen in Zeichenfolgen und wieder zurück in C ++ zu konvertieren. Die Eigenschaften, die ich möchte, sind str2num (num2str (x)) == x und num2str (str2num (x)) == x (soweit möglich). Die allgemeine Eigenschaft ist, dass num2str die einfachste rationale Zahl darstellen sollte, die, wenn sie auf die nächste darstellbare Gleitkommazahl gerundet wird, die ursprüngliche Zahl zurückgibt.
Bisher habe ich versucht, boost :: lexical_cast:
double d = 1.34;
string_t s = boost::lexical_cast<string_t>(d);
printf("%s\n", s.c_str());
// outputs 1.3400000000000001
Und ich habe std :: ostringstream ausprobiert, was bei stream.precision (16) für die meisten Werte zu funktionieren scheint. Bei Genauigkeit 15 oder 17 wird jedoch die Ausgabe für Dinge wie 1,34 entweder abgeschnitten oder hässlich. Ich glaube nicht, dass Präzision 16 garantiert bestimmte Eigenschaften hat, die ich benötige, und vermute, dass sie für viele Zahlen zusammenbricht.
Gibt es eine C ++ - Bibliothek, die eine solche Konvertierung hat? Oder ist eine solche Konvertierungsfunktion bereits irgendwo in den Standardbibliotheken / Boost vergraben.
Der Grund, warum diese Funktionen gewünscht werden, besteht darin, Gleitkommawerte in CSV-Dateien zu speichern und sie dann korrekt zu lesen. Außerdem möchten wir, dass die CSV-Dateien so weit wie möglich einfache Zahlen enthalten, damit sie von Menschen verarbeitet werden können.
Ich weiß, dass die Haskell Read / Show-Funktionen bereits die Eigenschaften haben, nach denen ich Ausschau halte, ebenso wie die BSD C-Bibliotheken. Die Standardreferenzen für String <-> Doppelkonvertierungen sind zwei Artikel aus PLDI 1990:
Wie man Gleitkommazahlen genau liest, erklärt Will KlingerGuy Steele et alJede darauf basierende C ++ - Bibliothek / Funktion wäre geeignet.
BEARBEITEN: Mir ist voll bewusst, dass Gleitkommazahlen ungenaue Darstellungen von Dezimalzahlen sind und dass 1,34 == 1,3400000000000001. Wie in den oben genannten Abhandlungen erwähnt, ist dies jedoch keine Entschuldigung für die Anzeige als "1.3400000000000001".
EDIT2: Dieses Papier erklärt genau, wonach ich suche:http://drj11.wordpress.com/2007/07/03/python-poor-printing-of-floating-point/