Round Double and Cast to String
I suppose this question is a follow up to a previous question I had regarding casting a double to a string.
I have an API where I'm given a string which represents a number. I need to round this number to 2 decimals of precision and return it as a string. My attempt to do this follows:
void formatPercentCommon(std::string& percent, const std::string& value, Config& config)
{
double number = boost::lexical_cast<double>(value);
if (config.total == 0)
{
std::ost开发者_如何学Cringstream err;
err << "Cannot calculate percent from zero total.";
throw std::runtime_error(err.str());
}
number = (number/config.total)*100;
// Format the string to only return 2 decimals of precision
number = floor(number*100 + .5)/100;
percent = boost::lexical_cast<std::string>(number);
return;
}
Unfortunately the cast captures "unrounded" values. (i.e. number = 30.63, percent = 30.629999999999) Can anyone suggest a clean way to round a double and cast it to a string so I get what one would naturally want?
Thanks in advance for the help. :)
Streams are the usual formatting facility in C++. In this case, a stringstream will do the trick:
std::ostringstream ss;
ss << std::fixed << std::setprecision(2) << number;
percent = ss.str();
You are probably already familiar with setprecision
from your previous post. fixed
here is used to make the precision affect the number of digits after the decimal point, instead of setting the number of significant digits for the whole number.
I haven't tested this, but I believe that the following should work:
string RoundedCast(double toCast, unsigned precision = 2u) {
ostringstream result;
result << setprecision(precision) << toCast;
return result.str();
}
This uses the setprecision
manipulator to change the precision of the ostringstream
that is doing the conversion.
double value = 12.00000;
std::cout << std::to_string(value).substr(0, 5) << std::endl;
Converting to a string while creating a substring will truncate extra zeros if you cannot use round()
for some reason. I ran into this situation the other day.
This would come out as 12.00 (don't forget the decimal character!)
Here's a version that does everything you want without re-inventing the wheel.
void formatPercentCommon(std::string& percent, const std::string& value, Config& config)
{
std::stringstream fmt(value);
double temp;
fmt >> temp;
temp = (temp/config.total)*100;
fmt.str("");
fmt.seekp(0);
fmt.seekg(0);
fmt.precision( 2 );
fmt << std::fixed << temp;
percent = fmt.str();
}
精彩评论