2

如何编写一个函数来格式化带有小数位的字符串,而不用尾随 0 或不必要的 9?鉴于小数是 2,这就是我所期望的:

0.999 -> 1.0
0.99 -> 0.99
1.01 -> 1.01
1.001 -> 1.0
123 -> 123.0
0 -> 0.0
0.1 -> 0.1

(如你所料的负面)

这是我到目前为止所拥有的,但它是非常丑陋的代码。有没有更好的方法来做到这一点?

string toStrMaxDecimals(double value, uint decimals) {
    value *= pow(10, decimals);
    value = round(value);
    value *= pow(0.1, decimals);
    string temp = boost::lexical_cast<string>(value); 
    size_t dot = temp.find('.');
    if (dot != string::npos) {
        if (temp.size() > dot + decimals + 1)
            temp.erase(dot + decimals + 1);
        if (*temp.rbegin() == '0')
            temp.erase(temp.find_last_not_of("0") + 1);
        if (*temp.rbegin() == '.')
            temp.append("0");
    } else {
        temp.append(".0");
    }
    return temp;
}
4

3 回答 3

10
std::string toStrMaxDecimals(double value, int decimals)
{
    std::ostringstream ss;
    ss << std::fixed << std::setprecision(decimals) << value;
    std::string s = ss.str();
    if(decimals > 0 && s[s.find_last_not_of('0')] == '.') {
        s.erase(s.size() - decimals + 1);
    }
    return s;
}
于 2009-05-22T23:28:32.073 回答
5

sprintf 将比 C++ 流更容易、更具可读性和更高的性能。你不需要自己做任何舍入或修剪。Sprintf 有这方面的标志。你可能想要类似的东西

sprintf(targetBuffer, "%.2g", floatingPointValue);

Sprintf 在 Java 中进行四舍五入,我很确定它在 C++ 中也是如此。

编辑:

对不起,我写的示例代码是为了你的例子。对于您的原始问题,将 %.2g 更改为 %.6g

编辑:

将 f 更改为 g 以抑制尾随零。

于 2009-05-23T00:11:20.923 回答
1

您是否考虑过使用普通的旧 sprintf 进行格式化?

它不会完全满足您的需要,但是如果您四舍五入到百分之一,然后将数字 sprintf 为 %f (用于浮点数)或 %lf (用于双浮点数)。

要四舍五入到第 100 位,您可以执行
num = num + ((int)(num-((int)num))*100)/100;

于 2009-05-22T22:58:43.787 回答