My application needs to convert double values to char* to write to a pipe that accepts only characters. The usual ways of doing this are using the sprintf() functio
Some systems provide dtostre
and dtostrf
conversion functions - might be worth benchmarking. You can look at sprintf()
source code (e.g. GNU version) for ideas, picking up the %e
, %f
and/or %g
formatting as desired, avoiding the format string interpretation step and even making it inlinable, and performance-tune to taste - you might be able to remove special casing for NaN, infinity and other values if you know you don't have to handle them.
You can use the std::ostream write
and std::istream read
methods with any data type you just have to reinterpret_cast the data as a char pointer:
double value = 5.0;
std::ostream os;
//...
os.write(reinterpret_cast<const char*>(&value), sizeof(value));
//..
std::istream is;
is.read(reinterpret_cast<char*>(&value), sizeof(value));
If you want to print any number that double type can support, use whatever library out there to do the job. It saves your sanity: Why does "dtoa.c" contain so much code?
If you want to print a subset of numbers in double type. For example, up to 4 digits after decimal point, and not more than 5 digits before decimal point, then you can round the number and convert to int type, before printing it out using division and mod. I can confirm the performance of this method.
EDIT: If you original purpose is to send the data for communication, then sending the binary form of double will be the fastest and most accurate method (no possible loss of precision due to conversion). The way to do this is explained in other answers.
The slow part of sprintf
on your system may not necessarily be converting the double, but parsing the format string. That might be good news for you as that is something that you could optimize away.
Additionally, try hard to document all the knowledge you have about range, accuracy, and nature of the double
values that you need to process, and use it to develop a special algorithm.
Assuming your inputs are never subnormal numbers, use a known fixed precision and accuracy, a relatively high performing result may look like this:
itoa((int)((f + 0.00001) * 10000))
However, the sprintf
and ostream
approaches you are already aware of are the only solutions that are completely general and portable.
if you wanna read data byte by byte. use this technique
double dbl = 2222;
char* ptr = (char*)(&dbl);
this will return lowest byte of dbl. and ptr++ will refer 2nd byte of dbl.
Using ftoa
will be slightly better than sprintf
as this is what it is using internally. See related question here Also look at how ftoa is implemented in your library source and see if you can improve on it for your specific scenarios.
It seems ftoa
is not standard at all, my bad. Here's a discussion showing an implementation which claims to be far faster that sprintf. You'd need to profile both on your own target environments, and implement with double rather than float.