как мне элегантно отформатировать строку на 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 ++.
Редактировать:
Извините, пример кода, который я написал, предназначен для вашего примера.Для вашего первоначального вопроса измените %.2g на %.6g
Редактировать:
Изменил f на g, чтобы подавить конечные нули.
Рассматривали ли вы возможность использования простого старого sprintf для форматирования?
Это не будет делать именно то, что вам нужно, но если вы округлите до сотых, а затем обработаете число как %f (для float) или %lf (для double float).
Чтобы округлить до 100'ths, вы могли бы сделать
num = num + ((int)(num-((int)num))*100)/100;