tags:

views:

470

answers:

9

What is the most optimal way to achieve the same as this?

void foo(double floatValue, char* stringResult)
{
    sprintf(stringResult, "%f", floatValue);
}
+11  A: 

http://www.cplusplus.com/reference/iostream/stringstream/

double d=123.456;
stringstream s;
s << d; // insert d into s

idontwanttortfm
If you are going to use this method (personally I'd choose boost::lexical_cast...) then I'd suggest using an istringstream. It may be more lightweight than a stringstream and, more importantly, you cannot get "<<" the wrong way around.
MattyT
+19  A: 

I'm sure someone will say boost::lexical_cast, so go for that if you're using boost, but it's basically the same as this anyway:

 #include <sstream>
 #include <string>

 std::string doubleToString(double d)
 {
    std::ostringstream ss;
    ss << d;
    return ss.str();
 }

Note that you could easily make this into a template that works on anything that can be stream-inserted (not just doubles).

Tyler McHenry
I should note that, due to the way the question was posed (as changing from C to C++), I interpreted "most optimal" as "most idiomatic" rather than "fastest executing".
Tyler McHenry
Regarding execution time of this approach, see: http://stackoverflow.com/questions/1250795/very-poor-boostlexicalcast-performance
Pukku
Even better: Use a template to handle any number of types, so you don't have to write an implementation for each conversion.
Matthew Iselin
This is the opposite of "optimal" in terms of execution time. It allocates memory for starters.
David Dolson
+2  A: 

I'd say sprintf is pretty much the optimal way. You may prefer snprintf over it, but it doesn't have much to do with performance.

Michael Krelin - hacker
Since the printf family of functions has to parse the formatting string at run time, there ought to be a faster way that doesn't have to do that.
David Dolson
That's right, but since underlying part of the printf has no publicly available entry point, the only way to do it is either to go for writing that yourself (that would duplicate code and therefore increase loading time! ;-)) or neglect the performance penalty of parsing formatting string. You can't be serious about the performance impact of parsing 2 (two!) characters (well, 3 including NUL), can you?
Michael Krelin - hacker
A: 

I'd probably go with what you suggested in your question, since there's no built-in ftoa() function and sprintf gives you control over the format. A google search for "ftoa asm" yields some possibly useful results, but I'm not sure you want to go that far.

David
+6  A: 

Boost::lexical_cast<>

greyfade
+1  A: 

On dinkumware STL, the stringstream is filled out by the C library snprintf.

Thus using snprintf formatting directly will be comparable with the STL formatting part. But someone once told me that the whole is greater than or equal to the sum of its known parts.

As it will be platform dependent as to whether stringstream will do an allocation (and I am quite sure that DINKUMWARE DOES NOT YET include a small buffer in stringstream for conversions of single items like yours) it is truely doubtful that ANYTHING that requires an allocation (ESPECIALLY if MULTITHREADED) can compete with snprintf.

In fact (formatting+allocation) has a chance of being really terrible as an allocation and a release might well require 2 full read-modify-write cycles in a multithreaded environment unless the allocation implementation has a thread local small heap.

That being said, if I was truely concerned about performance, I would take the advice from some of the other comments above, change the interface to include a size and use snprintf - i.e.

bool 
foo(const double d, char* const p, const size_t n){
     use snprintf......
     determine if it fit, etc etc etc.
}

If you want a std::string you are still better off using the above and instantiating the string from the resultant char* as there will be 2 allocations + 2 releases involved with the std::stringstream, std::string solution.

BTW I cannot tell if the "string" in the question is std::string or just generic ascii chars usage of "string"

pgast
BTW snprintf is terrible for uint32's approximately 10 time what a hand coded uitoa would be. I have done much work where we were publishing ascii numeric data (constrained by a protocol but since made binary) at rates approaching 1mm mps. NOT using snprintf was a huge win - think about it - branch prediction, the extra parse of the format string and having to handle all the different possible formats - ouch!
pgast
A: 

_gcvt or _gcvt_s.

MSN
Windows-only by the looks. (But that might be good enough.)
j_random_hacker
+2  A: 

The best thing to do would be to build a simple templatized function to convert any streamable type into a string. Here's the way I do it:

#include <sstream>
#include <string>

template <typename T>
const std::string to_string(const T& data)
{
   std::ostringstream conv;
   conv << data;
   return conv.str();
}

If you want a const char* representation, simply substitute conv.str().c_str() in the above.

hb2pencil
Only do this if you don't have access to boost. And if you don't have access to boost begin trying to get it! :)
MattyT
You have basically written boost::lexical_cast<T>! :) Clean, elegant and incredibly slow (because IOstreams are slow).
j_random_hacker
+1  A: 

If you use the Qt4 frame work you could go :

double d = 5.5;
QString num = QString::number(d);
OneOfOne