Ich habe eine Bibliothek, die doppelte Zahlen analysieren muss, die immer einen Punkt '.' als Dezimaltrennzeichen. Unglücklicherweise respektiert strtod() in diesem Fall das Gebietsschema, das möglicherweise ein anderes Trennzeichen verwendet, und daher kann das Parsen fehlschlagen. Ich kann locale() nicht festlegen - es ist nicht Thread-sicher. Also suche ich jetzt nach einer sauberen locale-unabhängigen Implementierung von strtod. Ich habe bis jetzt mehrere Implementierungen gefunden, aber alle sehen hacky oder einfach wie schlechter Code aus. Kann mir jemand eine gut getestete, funktionierende, saubere (ANSI) C-Implementierung empfehlen?Locale-unabhängige Implementierung von Strtod
Antwort
Ergreifen Sie einige bekannte Implementierung (die nicht von atof
abhängt), wie die mit Ruby verteilt: ruby_1_8/missing/strtod.c.
Es gibt auch gdtoa auf netlib, BSD-Lizenz: http://www.netlib.org/fp/gdtoa.tgz
die Antwort über Folgen, habe ich versucht, die Ruby-Implementierung bei ruby_1_8/missing/strtod.c verwenden. Doch für manche Eingänge gibt diese unterschiedliche Antworten auf gcc eingebauten Parser und strtod aus stdlib.h, sowohl auf Mac und Linux-Plattformen:
char * endptr ;
double value1 = 1.15507e-173 ;
double value2 = strtod("1.15507e-173", &endptr) ;
double value3 = test_strtod("1.15507e-173", &endptr) ;
assert(sizeof(double) == sizeof(unsigned long)) ;
printf("value1 = %lg, 0x%lx.\n", value1, *(unsigned long*)(&value1)) ;
printf("value2 = %lg, 0x%lx.\n", value2, *(unsigned long*)(&value2)) ;
printf("value3 = %lg, 0x%lx.\n", value2, *(unsigned long*)(&value3)) ;
assert(value1 == value2) ;
assert(value1 == value3) ;
die
value1 = 1.15507e-173, 0x1c06dace8bda0ee0.
value2 = 1.15507e-173, 0x1c06dace8bda0ee0.
value3 = 1.15507e-173, 0x1c06dace8bda0edf.
Assertion failed: (value1 == value3), function main, file main.c, line 16.
So druckt mein Rat ist, die gewählte Implementierung vor der Verwendung zu testen.
Warnung: Die vorgeschlagene Implementierung von Ruby enthält Fehler. Ich würde nicht der kleine Unterschied von gavin wies darauf hin, etwas dagegen, aber wenn Sie versuchen, so etwas wie „0,000000000000000000000000000000000000783475“ zu analysieren, werden Sie 0,0 statt 7.834750e-37 (wie die Aktien strtod() zurückkehrt.)
Andere bekommen Lösung:
#include <sstream>
#include "strtod_locale_independent.h"
extern "C" double strtod_locale_independent(const char* s)
{
std::istringstream text(s);
text.imbue(std::locale::classic());
double result;
text >> result;
return result;
}
Ich weiß nicht, wie schnell das ist, obwohl.
Das ist ungefähr 5x langsamer als die eingebaute strtod, und gibt Ihnen nicht den Endzeiger, der benötigt wird, wenn Sie ' Verwenden Sie es zum Parsen. –
Ja, Sie haben Recht. Aber der Punkt ist nicht Leistung. Es ist Gebietsschema-Abhängigkeit. Daher kann 'strtod()' nicht verwendet werden. –
Der Punkt ist, dass dies kein Ersatz für Strtod ist. –
- 1. Qt Segmentierung Fehler strtod
- 2. LynxOS strtod ist nicht dasselbe wie Linux
- 3. Valgrind: "Invalid read" mit c_str und strtod
- 4. Accessor-Implementierung von Eigenschaften
- 5. Implementierung von Web-Service-
- 6. eigene Implementierung von array_unique()
- 7. Unsafe Implementierung von TrustManager
- 8. JavaScript-Implementierung von Math.pow
- 9. Inkonsistente Implementierung von collections.abc
- 10. OpenJDK Implementierung von System.arraycopy
- 11. Implementierung von Java Comparator
- 12. Implementierung von Vector Clocks
- 13. Implementierung von NSCopying
- 14. JDK-Implementierung von Thread.join()
- 15. Korrekte Implementierung von Memento
- 16. Verschiedene Implementierung von Klassen
- 17. Python-Implementierung von YFilter
- 18. Implementierung von frama-clang
- 19. Python-Implementierung von Parsec?
- 20. Kostenlose Implementierung von Elgamal
- 21. Korrekte Implementierung von min
- 22. Implementierung von COMET clientside
- 23. Async-Implementierung von IValueConverter
- 24. Implementierung von std :: initializer_list
- 25. JavaScript Implementierung von VIM
- 26. winzige Implementierung von jquery
- 27. Anpassbare Implementierung von sprintf()
- 28. Implementierung von BufferedIterator
- 29. Implementierung von Importen
- 30. Implementierung von GetHashCode
Vielen Dank. Genau das habe ich gesucht. Eine gut getestete und saubere Implementierung. – bert
Ich fürchte, das ist keine korrekte Implementierung, es hat sich nicht um das Runden gekümmert, was eine sehr wichtige Sache bei der String-Doppelwandlung ist. Bitte googeln Sie "Korrekt abgerundete Dezimal zu Fließkomma-Konvertierung" und schauen Sie. – amanjiang