Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++ difficulties with stringstream, setw and setprecision

I was trying to format a matrix using stringstream, setw and setprecision. The code looks like this:

template <typename T>
std::string format(std::vector<T> &a, int m, int n, int lda)
{
    std::stringstream ss;
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            ss << std::setw(6);
            ss << a[i + j * lda];
            ss << std::setprecision(2);
        }
        if (i < m - 1)
            ss << std::endl;
    }
    return ss.str();
}

int main()
{
    const int LDA = 5;
    const int N = LDA;

    std::vector<double> a = {
        6.39, 0.00, 0.00, 0.00, 0.00,
        0.13, 8.37, 0.00, 0.00, 0.00,
        -8.23, -4.46, -9.58, 0.00, 0.00,
        5.71, -6.10, -9.25, 3.72, 0.00,
        -3.18, 7.21, -7.42, 8.54, 2.51};

    std::cout << format(a, N, N, LDA) << std::endl;

    return 0;
}

The output looks like this:

  6.39  0.13  -8.2   5.7  -3.2
     0   8.4  -4.5  -6.1   7.2
     0     0  -9.6  -9.2  -7.4
     0     0     0   3.7   8.5
     0     0     0     0   2.5
  1. Why are values like -8.2, 8.4 rounded?
  2. Why aren’t zeros formatted?

I was expecting an output like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

   6.39   0.13  -8.23   5.71  -3.18
   0.00   8.37  -4.46  -6.10   7.21
   0.00   0.00  -9.58  -9.25  -7.42
   0.00   0.00   0.00   3.72   8.54
   0.00   0.00   0.00   0.00   2.51

How do I format it correctly?

>Solution :

You need to move std::setprecision(2) to before you start printing, otherwise the first value will have the default precision. This setting is active until you replace it with something else, so you only need to do it once.

You also need to set the stream in std::fixed mode.

Example:

template <typename T>
std::string format(std::vector<T> &a, int m, int n, int lda) {
    std::stringstream ss;
    
    ss << std::fixed << std::setprecision(2);    // <- here

    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            ss << std::setw(6) << a[i + j * lda];
        }
        if (i < m - 1) ss << '\n'; // std::endl; is pointless
    }
    return ss.str();
}

Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading