我如何在C++中优雅地格式化字符串,以便它被舍入到6个小数位并且有额外的'0'或'9'被修剪

Nei*_*l G 2 c++ string formatting string-formatting

如何编写一个格式化带小数位数的字符串的函数,而不是尾随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
Run Code Online (Sandbox Code Playgroud)

(你期望的负面影响)

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

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;
}
Run Code Online (Sandbox Code Playgroud)

小智 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;
}
Run Code Online (Sandbox Code Playgroud)


Jhe*_*ico 5

与C++流相比,sprintf将更容易,更易读,性能更高.您不需要自己进行任何舍入或修剪.Sprintf有标志.你可能想要这样的东西

sprintf(targetBuffer, "%.2g", floatingPointValue);
Run Code Online (Sandbox Code Playgroud)

Sprintf在Java中进行舍入,我很确定它也适用于C++.

编辑:

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

编辑:

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