Как мне элегантно отформатировать строку в C ++, чтобы она была округлена до 6 десятичных знаков и иметь дополнительные '0 или' обрезанные 9 - PullRequest
1 голос
/ 23 мая 2009

Как мне написать функцию, которая форматирует строку с десятичными цифрами, без конечных 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;
}

Ответы [ 3 ]

9 голосов
/ 23 мая 2009
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;
}
5 голосов
/ 23 мая 2009

sprintf будет намного проще, более читабельным и более производительным, чем потоки C ++. Вам не нужно делать какие-либо округления или обрезки самостоятельно. У Sprintf есть флаги для этого. Вы, вероятно, хотите что-то вроде

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

Sprintf выполняет округление в Java, и я почти уверен, что оно будет и в C ++.

EDIT:

Извините, пример кода, который я написал, для вашего примера. Для исходного вопроса измените% .2g на% .6g

РЕДАКТИРОВАТЬ:

Изменено f на g, чтобы подавить конечные нули.

1 голос
/ 23 мая 2009

Рассматривали ли вы использовать простой старый sprintf для форматирования?

Это не будет делать именно то, что вам нужно, но если вы округлите до одной сотой, а затем наберите число как% f (для float) или% lf (для double float).

Чтобы округлить до 100, вы можете сделать
num = num + ((int) (num - ((int) num)) * 100) / 100;

...