2014-11-29 14 views
6

Ho bisogno di aiuto per la formattazione dell'output con flussi C++. Vorrei stampare numeri con un punto decimale fisso e al massimo 2 punti finali. Ho provato la seguente:Numero limite di zeri finali per uscita fissa

#include <iostream> 
#include <iomanip> 
using namespace std; 

int main(int argc, char **argv) 
{ 
    float testme[] = { 0.12345, 1.2345, 12.345, 123.45, 1234.5, 12345 }; 

    std::cout << std::setprecision(2) << std::fixed; 

    for(int i = 0; i < 6; ++i) 
    { 
     std::cout << testme[i] << std::endl; 
    } 

    return 0; 
} 

L'output è:

0.12 
1.23 
12.35 
123.45 
1234.50 
12345.00 

Ma mi piacerebbe avere

0.12 
1.23 
12.35 
123.45 
1234.5 
12345 

Posso raggiungere questo obiettivo senza utilizzare ulteriore manipolazione delle stringhe?

risposta

1

Questo funziona (http://ideone.com/CFcVhu), ma non è così bello ...

#include <iostream> 
#include <iomanip> 
using namespace std; 

int main(int argc, char **argv) 
{ 
    float testme[] = { 0.12345, 1.2345, 12.345, 123.45, 1234.5, 12345 }; 

    //std::cout << std::setprecision(2) << std::fixed; 

    for(int i = 0; i < 6; ++i) 
    { 
     std::cout << ((int)(testme[i]*100.0))/100.0f << std::endl; 
    } 

    return 0; 
} 
2

Non sono a conoscenza di un manipolatore atto a soddisfare, da cui è possibile utilizzare:

#include <iostream> 
#include <iomanip> 
#include <cmath> 

template <typename T> 
struct Fixed 
{ 
    const T& value; 
    const unsigned precision; 
    const T significant; 

    Fixed(const T& value, unsigned precision) 
    : value(value), precision(precision), significant(std::pow(10, precision)) 
    {} 

    void write(std::ostream& stream) const { 
     // Adjust stream settings 
     std::ostream::char_type restore_fill = stream.fill('0'); 
     std::ios_base::fmtflags restore_flags = stream.setf(
      std::ios_base::fixed, std::ios_base::floatfield); 
     std::streamsize restore_precision = stream.precision(0); 

     // Split the floating point into an integral and rounded fractional part 
     T integral; 
     unsigned long fractional = std::round(significant * std::modf(value, &integral)); 

     // Determine the length of the fractional part 
     unsigned digits = precision; 
     while(fractional && fractional % 10 == 0) { 
      fractional /= 10; 
      --digits; 
     } 

     // Carry over to the integral part 
     if(! digits && fractional) { 
      integral += 1; 
      fractional = 0; 
     } 

     // Output 
     stream << integral; 
     if(fractional) { 
      stream << '.' << std::setw(digits) << fractional; 
     } 

     // Restore stream settings 
     stream.precision(restore_precision); 
     stream.flags(restore_flags); 
     stream.fill(restore_fill); 
    } 
}; 

template <typename T> 
inline Fixed<T> fixed(const T& value, unsigned precision) { 
    return Fixed<T>(value, precision); 
} 

template <typename T> 
inline std::ostream& operator << (std::ostream& stream, const Fixed<T>& value) { 
    value.write(stream); 
    return stream; 
} 

int main(int argc, char **argv) 
{ 
    float testme[] = { 0.12345, 1.2345, 12.345, 123.45, 1234.5, 12345 }; 
    for(int i = 0; i < 6; ++i) 
    { 
     std::cout << fixed(testme[i], 2) << std::endl; 
    } 

    return 0; 
} 
-1

In altre parole , vuoi rappresentare un numero utilizzando 2 cifre decimali se è inferiore a 1000 (sempre positivo?), 1 decimale se è inferiore a 10000 e zero altrimenti. Hmm, come si potrebbe codificarlo?