如何优雅地格式化 C++ 中的字符串,使其四舍五入到小数点后 6 位并修剪掉多余的“0”或“9”
-
23-08-2019 - |
题
如何编写一个函数来格式化带有小数位的字符串,而无需尾随 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;
不隶属于 StackOverflow