将双精度数四舍五入并转换为字符串

4

我想这个问题是我之前关于将double转换为字符串的问题的后续。

我有一个API,其中给定了表示数字的字符串。我需要将此数字四舍五入到2位小数,并将其作为字符串返回。我的尝试如下:

void formatPercentCommon(std::string& percent, const std::string& value, Config& config)
{
    double number = boost::lexical_cast<double>(value);
    if (config.total == 0)
    {
        std::ostringstream 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;
}

很不幸,转换得到的值是“未舍入”的。 (例如:number = 30.63, percent = 30.629999999999) 有没有人能够建议一种简洁的方法来将double类型数值舍入并转换为字符串,以便得到自然想要的结果?

提前感谢您的帮助。 :)

4个回答

9

流是C++中通常的格式化工具。在这种情况下,stringstream就可以胜任:

std::ostringstream ss;
ss << std::fixed << std::setprecision(2) << number;
percent = ss.str();

你可能已经熟悉了上一篇文章中的setprecision。这里使用fixed来使精度影响小数点后的数字位数,而不是设置整个数字的有效数字位数。


非常感谢!我真的不想使用创建临时字符数组并使用snprintf()格式化的方法。 :) - Rico

3

我没有测试过,但我相信以下内容应该有效:

string RoundedCast(double toCast, unsigned precision = 2u) {
    ostringstream result;
    result << setprecision(precision) << toCast;
    return result.str();
}

使用setprecision操纵器更改进行转换的ostringstream的精度。


2
double value = 12.00000;

std::cout << std::to_string(value).substr(0, 5) << std::endl;

如果由于某些原因无法使用round(),在创建子字符串时转换为字符串将截断多余的零。我最近遇到了这种情况。

这会变成12.00(不要忘记小数点符号!)


是的,谢谢。我很久没有访问这个网站了,忘了使用代码编辑器。下次一定记得格式化! - user14268276
我使用了类似以下的代码: res = res.substr(0, res.length() - 5); 来去掉多余的零。 - Ac Hybl

0

这里有一个版本,可以在不重复造轮子的情况下实现你想要的一切。

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();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接