如何优雅地格式化 C++ 中的字符串,使其四舍五入到小数点后 6 位并修剪掉多余的“0”或“9”

StackOverflow https://stackoverflow.com/questions/900326

如何编写一个函数来格式化带有小数位的字符串,而无需尾随 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;
}
有帮助吗?

解决方案

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

其他提示

sprintf的是要容易得多,更可读的和超过C ++流的性能。你不需要做任何四舍五入或修剪自己。 sprintf的具有该标志。你可能想是这样

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

的sprintf确实在Java的舍入,而且我敢肯定它会在C ++中也是如此。

编辑:

对不起,我写的示例代码是你的榜样。对于你原来的问题,更改%0.2克至是%.6g

编辑:

改变F至g至抑制尾随零。

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

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

要四舍五入到百分之一,你可以这样做
num = num + ((int)(num-((int)num))*100)/100;

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top