2012-09-07 27 views
6

hay una manera de modificar std :: stod() para aumentar el número de dígitos decimales en (cadena a doble) conversión y obligarlo a usar la configuración regional de EE. UU.Cómo modificar std :: stod (cadena a doble) para separador decimal y número de dígitos

Tengo una aplicación Qt que se puede ejecutar en modo de consola o 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(); 
} 

Dentro de esta aplicación tengo una cadena de doble método que envuelve el nuevo 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; 
} 

Curiosamente, mientras que en el modo de consola la cadena para la doble conversión espera una cadena con punto como separador decimal, en el modo gui espera una cadena con coma. Además, ya que estaba previamente usando istringstream:

istringstream totalSString(valueAsString); 
totalSString >> valueAsDouble; 

Noté que stod trunca el resultado doble a sólo 3 dígitos decimales, mucho menos que istringstream.

¿Hay alguna manera de aumentar el número de dígitos decimales y forzar a std :: stod a usar la configuración regional de los EE. UU. Para la conversión?

Gracias :-)

EDITADO:

Si trato de este script:

// 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; 
    } 
} 

me dieron estos resultados:

modo "consola":

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

modo "GUI":

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

Así que claramente hay algo que influye stod() comportamiento!

+1

'stod' se define como el uso de' sprintf' con '% f'. No es configurable. –

+0

Si le preocupa la velocidad de ejecución en tiempo real y desea la independencia del entorno local, y no le preocupan los tiempos de compilación potencialmente peores, [Boost.Spirit] (http://www.boost.org/libs/spirit/) .Qi es absolutamente el camino a seguir. – ildjarn

+0

Tropezó con esto y se sorprendió de que Stod trunca los valores. Pero el problema es que std :: cout no genera el valor completo. Debe establecer una mayor precisión: std :: cout << std :: setprecision (16); – ead

Respuesta

7

std::stod y sus parientes fueron diseñados para proporcionar un sencilla, la conversión rápida de una cadena a un tipo numérico. (divulgación completa: es mi diseño) Entonces, no, no hay configuraciones regionales; lo que ves, es lo que tienes.

+0

Entonces, solo por curiosidad, ¿por qué tengo este comportamiento diferente en modo gui/consola? Debe haber algo que las bibliotecas de Qt establecen que influyen en el comportamiento stod. – Antonello

+0

@ Antonello - lo siento, no tengo experiencia con Qt. –

+2

Solo para aclarar, stod() está influenciado por la configuración regional actual, al menos en GCC. Por ejemplo, para asegurarse de que usará el punto como separador decimal, debe usar #include y setlocale (LC_ALL, "C") (eso es lo predeterminado, pero claramente Qt debe configurarlo en la configuración de la computadora en ejecución, por lo que debe sobrescribir la anulación de Qt ;-)) – Antonello

1

std::stod es una forma genérica de convertir un std::string en un doble. Si desea algo más específico, debe implementarlo usted mismo.

Por ejemplo:

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

sí, esto es lo que estaba usando en realidad, pero es bastante lento, y estoy bastante preocupado con la velocidad ... – Antonello

+0

Bueno, la pregunta era "cómo teak std :: stod". La respuesta triste es "no puedes".Si realmente descubres que usar stringstreams es un cuello de botella en tu código, debes optimizarlo. Pero recuerda, no optimices prematuramente. – mfontanini

Cuestiones relacionadas