2012-09-07 13 views
6

czy istnieje sposób na ulepszenie std :: stod() w celu zwiększenia liczby cyfr dziesiętnych w ciągu (ciąg do podwójnego) konwersja i zmusić go do używania locale w USA?Jak zmienić std :: stod (ciąg na podwójne) dla separatora dziesiętnego i liczby cyfr

Mam aplikacji Qt, które mogą być uruchamiane zarówno w trybie konsoli lub gui:

if (opt->getFlag('c') || opt->getFlag("console")){ 
    ThreadManager modelMainThread; 
    modelMainThread.runFromConsole(inputFileName,scenarioName); 
} 
else { 
    QApplication app(argc, argv); 
    MainWindow mainWin; 
    mainWin.show(); 
    return app.exec(); 
} 

w tym wniosku Mam ciąg do metody podwójnego która otacza nową C++ 11 STOD:

double s2d (const string &string_h) const { 
    try { 
    return stod(string_h); 
    } catch (...) { 
    if (string_h == "") return 0; 
    else { 
     cout << "error!" << endl; 
    } 
    } 
    return 0; 
} 

Dziwne, gdy w trybie konsoli ciąg do podwójnej konwersji oczekuje ciągu znaków z kropką jako separatora dziesiętnego, w trybie gui zamiast tego oczekuje ciąg znaków z przecinkiem. Ponadto, jak już wcześniej przy użyciu istringstream:

istringstream totalSString(valueAsString); 
totalSString >> valueAsDouble; 

zauważyłem, że Stod obcina uzyskany podwójny do zaledwie 3 cyfr po przecinku, znacznie mniej niż istringstream.

Czy istnieje sposób na zwiększenie liczby cyfr dziesiętnych i na wymuszenie użycia std :: stod w USA w celu konwersji?

Dzięki :-)

edytowany:

Gdy próbuję tego skryptu:

// testing stod() .. 
vector<string> numbers; 
numbers.push_back("123.1234567890"); 
numbers.push_back("123.1234"); 
numbers.push_back("123,1234567890"); 
numbers.push_back("123,1234"); 
double outd; 
for(uint i=0;i<numbers.size();i++){ 
    try { 
     outd = stod(numbers[i]); 
     cout << "Conversion passed: " << numbers[i] << " - " << outd << endl; 
    } catch (...) { 
     cout << "Conversion DID NOT passed: " << numbers[i] << " - " <<endl; 
    } 
} 

mam te wyniki:

tryb

"konsola":

Conversion passed: 123.1234567890 - 123.123 
Conversion passed: 123.1234 - 123.123 
Conversion passed: 123,1234567890 - 123 
Conversion passed: 123,1234 - 123 
Tryb

"gui":

Conversion passed: 123.1234567890 - 123 
Conversion passed: 123.1234 - 123 
Conversion passed: 123,1234567890 - 123.123 
Conversion passed: 123,1234 - 123.123 

więc wyraźnie, że jest coś wpływającym Stod() zachowanie!

+1

'stod' definiowane jest jako' sprintf' z '% f'. Nie można go konfigurować. –

+0

Jeśli obawiasz się nieprzetworzonej szybkości działania i chcesz uzyskać niezależność od ustawień narodowych i nie martwisz się o potencjalnie gorsze czasy kompilacji, [Boost.Spirit] (http://www.boost.org/libs/spirit/) .Qi to absolutnie droga. – ildjarn

+0

Natknęliśmy się na to i byłem zszokowany, że stodka skracają wartości. Problem polega jednak na tym, że std :: cout nie wyprowadza całej wartości. Musisz ustawić wyższą precyzję: std :: cout << std :: setprecision (16); – ead

Odpowiedz

7

std::stod i jego krewni zostały zaprojektowane, aby zapewnić prosty, szybką konwersję z ciągiem do typu numerycznego. (pełne ujawnienie: to mój projekt) Tak, nie, nie ma ustawień regionalnych; to co widzisz Jest Tym Co dostajesz.

+0

Więc, tylko dla ciekawości, dlaczego mam inne zachowanie w trybie gui/konsoli? Musi być coś, co zestaw bibliotek Qt wpływa na zachowanie stod. – Antonello

+0

@Antonello - przepraszam, nie mam doświadczenia z Qt. –

+2

Po prostu dla wyjaśnienia, stod() jest pod wpływem bieżącego locale, przynajmniej w GCC. Przykładowo, aby upewnić się, że użyje kropki jako separatora dziesiętnego, należy użyć #include i setlocale (LC_ALL, "C") (jest to ustawienie domyślne, ale wyraźnie Qt musi ustawić go na język działający na komputerze lokalnym, więc trzeba przesłonić nadpisanie Qt ;-)) – Antonello

1

std::stod to w pewien sposób ogólny sposób przekształcania std::string w podwójne. Jeśli chcesz czegoś bardziej konkretnego, powinieneś go wdrożyć samodzielnie.

Na przykład:

double my_stod(const std::string &valueAsString) { 
    istringstream totalSString(valueAsString); 
    double valueAsDouble; 
    // maybe use some manipulators 
    totalSString >> valueAsDouble; 
    if(!totalSString) 
     throw std::runtime_error("Error converting to double");  
    return valueAsDouble; 
} 
+0

Tak, to jest to, czego faktycznie używałem, ale jest to dość powolne, i jestem dość zaniepokojony prędkością .. – Antonello

+0

Cóż, pytanie brzmiało "jak teak std :: stod". Odpowiedź brzmi: "nie możesz".Jeśli naprawdę dowiadujesz się, że używanie stringów jest wąskim gardłem w twoim kodzie, powinieneś go zoptymalizować. Ale pamiętaj, nie optymalizuj przedwcześnie. – mfontanini