问题
I have a C++
program using SDL
. During rendering, I need to draw some graphics components. I sometimes need to convert double
variables, rounded to one decimal, to std::string
.
For this, I'm currently using a ostringstream
object and it works fine.
std::ostringstream ss;
ss << std::fixed << std::setprecision(1) << x;
However, I'm wondering if this way of converting variables is a good idea with regards to performance.
I've tried to round the double
variables with std::to_string(std::round(x * 10) / 10))
, but it didn't work -- I still got output like 2.500000000
.
- Is there another solution?
- Does
ostringstream
incur a heavy cost?
回答1:
You can't specify the precision with std::to_string
as it is a direct equivalent to printf
with the parameter %f
(if using double
).
If you are concerned about not allocating each time the stream, you can do the following :
#include <iostream>
#include <sstream>
#include <iomanip>
std::string convertToString(const double & x, const int & precision = 1)
{
static std::ostringstream ss;
ss.str(""); // don't forget to empty the stream
ss << std::fixed << std::setprecision(precision) << x;
return ss.str();
}
int main() {
double x = 2.50000;
std::cout << convertToString(x, 5) << std::endl;
std::cout << convertToString(x, 1) << std::endl;
std::cout << convertToString(x, 3) << std::endl;
return 0;
}
It outputs (see on Coliru) :
2.50000
2.5
2.500
I didn't check the performance though... but I think you could even do better by encapsulating this into a class (like only call std::fixed
and std::precision
once).
Otherwise, you could still use sprintf
with the parameters that suits you.
Going a little further, with an encapsulating class that you could use as a static instance or a member of another class... as you wish (View on Coliru).
#include <iostream>
#include <sstream>
#include <iomanip>
class DoubleToString
{
public:
DoubleToString(const unsigned int & precision = 1)
{
_ss << std::fixed;
_ss << std::setprecision(precision);
}
std::string operator() (const double & x)
{
_ss.str("");
_ss << x;
return _ss.str();
}
private:
std::ostringstream _ss;
};
int main() {
double x = 2.50000;
DoubleToString converter;
std::cout << converter(x) << std::endl;
return 0;
}
Another solution without using ostringstream
(View on Coliru) :
#include <iostream>
#include <string>
#include <memory>
std::string my_to_string(const double & value) {
const int length = std::snprintf(nullptr, 0, "%.1f", value);
std::unique_ptr<char[]> buf(new char[length + 1]);
std::snprintf(buf.get(), length + 1, "%.1f", value);
return std::string(buf.get());
}
int main(int argc, char * argv[])
{
std::cout << my_to_string(argc) << std::endl;
std::cout << my_to_string(2.5156) << std::endl;
}
来源:https://stackoverflow.com/questions/34744591/convert-double-to-string-quickly-observing-given-precision