come faccio elegantemente stringa di formato in C ++ in modo che sia arrotondato a 6 cifre decimali e ha extra '0 di o' 9 di rifilato

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

Domanda

Come faccio a scrivere una funzione che formatta una stringa con decimali cifre, senza finali 0 di inutili o 9 di? Dato che è decimali 2, ecco cosa mi aspetto:

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

(negativi come ci si aspetterebbe)

Ecco quello che ho finora, ma è abbastanza brutto codice. C'è un modo migliore per fare questo?

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;
}
È stato utile?

Soluzione

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

Altri suggerimenti

sprintf sta per essere molto più facile, più leggibile e più prestazioni rispetto a flussi di C ++. Non è necessario fare eventuali arrotondamenti o taglio da soli. Sprintf ha bandiere per questo. Probabilmente si desidera qualcosa di simile

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

sprintf fa l'arrotondamento in Java, e sono abbastanza sicuro che lo farà in C ++ pure.

EDIT:

Siamo spiacenti, il codice di esempio che ho scritto è per il vostro esempio. Per la vostra domanda originale, modificare il% .2g a% .6g

EDIT:

Modificato f per g di sopprimere zeri finali.

Hai pensato di usare semplice vecchia sprintf a fare la formattazione?

Non farà esattamente quello che ti serve, ma se si arrotondare a 1/100, e poi sprintf il numero come% f (per float) oppure% lf (per doppio galleggiante).

Per arrotondare a 100'ths, si potrebbe fare
num = num + ((int) (num - ((int) num)) * 100) / 100;

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top