-1

I want to know how I can, in c++, print for example 10 as 10.0000, or 10.1 as 10.1000. I want the total number of digits to be the same and pad with '0' the empty spaces on the right. I read about 'setprecision', but it doesn't add '0'. 'fixed' is the numbers of digits after the floating point, and I want the total number of digits to be fixed. is there a way to do this, not using printf?

Cœur
  • 37,241
  • 25
  • 195
  • 267
littlerunaway
  • 443
  • 2
  • 8
  • 18

2 Answers2

0

You can do something like this: (considering you want a fixed length of 5)

int precision(double num){
    int p;
    if (num <1)
        p = 5;
    else if (num <10)
        p = 4;
    else if (num <100)
        p = 3;
    else if (num <1000)
        p = 2;
    else if (num <10000)
        p = 1;
    else
        p = 0;
    return p;
}

int main(){
    double num;
    std::cin>>num;
    std::cout <<std::fixed <<std::setprecision(precision(num)) << num <<std::endl;
    return 0;
}

As you required, if the number of digits After decimal is more than 5 it will be truncated.

Now, implement your own logic for what you want to do if number of digits Before decimal point is more than 5. :)

  • thanx, that seems to be a good solution. I have to admit I'm a bit surprised there isn't some built in function for this. it seems basic output formating for me. – littlerunaway Jun 05 '14 at 22:13
0

You will ultimately need to find out the length in digits of the double. I'm not entirely sure how to go about that in a safe way but fortunately I can show you an example where we can do this with integers.

Basically I would recommend creating a new facet class that implements the custom formatting inside do_put(). Then imbue this class into your stream. The exact same thing as below can be done for the overload of do_put() that takes a double as its last argument, plus a few changes to the for loop.

#include <iostream>
#include <iomanip>

class num_put : public std::num_put<char>
{
    iter_type do_put( iter_type out, std::ios_base& str, char, long v ) const
    {
        std::streamsize width = str.width();
        int             digits = num_digits(v);

        if (digits > width)
            for (std::streamsize i(0); i < digits - width; ++i)
                v /= 10;
            /*  v = static_cast<int>(v * 10) / 10.; // use this instead for
            */                                      // floating-point

        str.flags(std::ios_base::left);
        out = std::num_put<char>::do_put(out, str, '0', v);

        str.width(width);
        return out;
    }
private:
    template<class T>
    static int num_digits(T num) // only works for integral types
    {
        int length = 1;
        while (num /= 10)
            ++length;
        return length;
    }
};

int main()
{
    std::cout.imbue(std::locale(std::cout.getloc(), new num_put));

    std::cout << std::setw(5) << 123;       // 12300
    std::cout << std::setw(5) << 123456789; // 12345
}
David G
  • 94,763
  • 41
  • 167
  • 253