4
\$\begingroup\$

Works for any 2D matrix represented by a 1D array. Comments and criticism welcome. Also wondering whether the code can be made shorter. It's really messy right now.

#include <stdio.h>

typedef float fpoint_t; 

void print(fpoint_t* m, int row_size, int col_size)
{

    int i, j;
    printf(" array([");

    if(row_size == 1 || col_size == 1)
    {
        int len = row_size == 1? col_size : row_size;

        if(col_size == 1)
        {
            for(i = 0; i < len; i++)
            {
                if(i == len - 1)
                    printf("%.2e", m[i]);

                else
                {
                    if(m[i] >= 0) printf(" %5.2e, ", m[i]);
                    else printf("%5.2e, ", m[i]);
                    if((i + 1) % 6 == 0) 
                        printf("\n\t");
                }   
            }
        }
        else
        {
            for(i = 0; i < len; i++)
            {
                if(i == 0)
                    printf(" %.2e\n", m[i]);
                else if(i == len - 1)
                    printf("\t %.2e", m[i]);

                else
                {
                    if(m[i] >= 0) printf("\t %5.2e,\n", m[i]);
                    else printf("\t %5.2e,\n", m[i]);
                }   
            }
        }

        printf(" ])\n");

        return;
    }

    if (row_size > 10)
    {
        for(i = 0; i < 3; i++)
        {
            if(i == 0)
                printf("[ ");
            else
                printf("\t[ ");
            if(col_size > 10)
            {
                for(j = 0; j < 3; j++)
                {
                    if(j < 2)
                    {
                        if(m[i * col_size + j] >= 0) printf(" %5.4e,\t", m[i * col_size + j]);
                        else printf("%5.4e,\t", m[i * col_size + j]);
                    }
                    else
                    {
                        if(m[i * col_size + j] >= 0) printf(" %5.4e, ", m[i * col_size + j]);
                        else printf("%5.4e, ", m[i * col_size + j]);
                    }

                }

                printf("...,  ");

                if(m[i * col_size + col_size - 3] >= 0) 
                    printf(" %5.4e,\t\n\t", m[i * col_size + col_size - 3]);
                else 
                    printf("%5.4e,\t\n\t", m[i * col_size + col_size - 3]);

                if(m[i * col_size + col_size - 2] >= 0) 
                    printf("   %5.4e,\t", m[i * col_size + col_size - 2]);
                else 
                    printf("  %5.4e,\t", m[i * col_size + i]);

                if(m[i * col_size + col_size - 1] >= 0) 
                    printf(" %5.4e", m[i * col_size + col_size - 1]);
                else 
                    printf("%5.4e", m[i * col_size + col_size - 1]);
            }

            else
            {
                for(j = 0; j < col_size; j++)
                {
                    if(j != col_size - 1)
                        printf("%.6g, ", m[i * col_size + j]);
                    else 
                        printf("%.6g", m[i * col_size + j]);
                }
            }
            printf(" ],\n");
        }

        printf("\t...,\n");

        for(i = row_size - 3; i < row_size; i++)
        {
            printf("\t[ ");
            if(col_size > 10)
            {
                for(j = 0; j < 3; j++)
                {
                    if(j < 2)
                    {
                        if(m[i * col_size + j] >= 0) printf(" %5.4e,\t", m[i * col_size + j]);
                        else printf("%5.4e,\t", m[i * col_size + j]);
                    }
                    else
                    {
                        if(m[i * col_size + j] >= 0) printf(" %5.4e, ", m[i * col_size + j]);
                        else printf("%5.4e, ", m[i * col_size + j]);
                    }

                }

                printf("...,  ");

                if(m[i * col_size + col_size - 3] >= 0) 
                    printf(" %5.4e,\t\n\t", m[i * col_size + col_size - 3]);
                else 
                    printf("%5.4e,\t\n\t", m[i * col_size + col_size - 3]);

                if(m[i * col_size + col_size - 2] >= 0) 
                    printf("   %5.4e,\t", m[i * col_size + col_size - 2]);
                else 
                    printf("  %5.4e,\t", m[i * col_size + i]);

                if(m[i * col_size + col_size - 1] >= 0) 
                    printf(" %5.4e", m[i * col_size + col_size - 1]);
                else 
                    printf("%5.4e", m[i * col_size + col_size - 1]);
            }

            else
            {
                for(j = 0; j < col_size; j++)
                {
                    if(j != col_size - 1)
                        printf("%.6g, ", m[i * col_size + j]);
                    else 
                        printf("%.6g", m[i * col_size + j]);
                }
            }
            if(i == row_size - 1)
                printf(" ]])\n");
            else
                printf(" ],\n");
        }
    }

    else
    {
        for(i = 0; i < row_size; i++)
        {
            if(i == 0)
                printf("[ ");
            else
                printf("\t[ ");

            if(col_size > 10)
            {
                for(j = 0; j < 3; j++)
                {
                    if(j < 2)
                    {
                        if(m[i * col_size + j] >= 0) printf(" %5.4e,\t", m[i * col_size + j]);
                        else printf("%5.4e,\t", m[i * col_size + j]);
                    }
                    else
                    {
                        if(m[i * col_size + j] >= 0) printf(" %5.4e, ", m[i * col_size + j]);
                        else printf("%5.4e, ", m[i * col_size + j]);
                    }

                }

                printf("...,  ");

                if(m[i * col_size + col_size - 3] >= 0) 
                    printf(" %5.4e,\t\n", m[i * col_size + col_size - 3]);
                else 
                    printf("%5.4e,\t\n", m[i * col_size + col_size - 3]);

                if(m[i * col_size + col_size - 2] >= 0) 
                    printf("\t   %5.4e,\t", m[i * col_size + col_size - 2]);
                else 
                    printf("\t  %5.4e,\t", m[i * col_size + i]);

                if(m[i * col_size + col_size - 1] >= 0) 
                    printf(" %5.4e", m[i * col_size + col_size - 1]);
                else 
                    printf("%5.4e", m[i * col_size + col_size - 1]);
            }

            else
            {
                for(j = 0; j < col_size; j++)
                {
                    if(j != col_size - 1)
                        printf("%.6g, ", m[i * col_size + j]);
                    else 
                        printf("%.6g", m[i * col_size + j]);
                }
            }
            if(i == row_size - 1)
                printf(" ]])\n");

            else
                printf(" ],\n");
        }
    }
}
\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

A lot of code is repetitive with only slight changes in format. Instead of ...

       for(j = 0; j < 3; j++)
            {
                if(j < 2)
                {
                    if(m[i * col_size + j] >= 0) printf(" %5.4e,\t", m[i * col_size + j]);
                    else printf("%5.4e,\t", m[i * col_size + j]);
                }
                else
                {
                    if(m[i * col_size + j] >= 0) printf(" %5.4e, ", m[i * col_size + j]);
                    else printf("%5.4e, ", m[i * col_size + j]);
                }

            }

... consider the following conditional values for "%s" which may reduce code's printf()s by 75% or more

       #define JLOOP 3
       for (j = 0; j < JLOOP; j++) {
         const char *pre = ""; // shown here for illustration, even though always ""
         const char *post = j < JLOOP - 1 ? ",\t" : "";
         //         v--- add space to use space for positive numbers
         printf("%s% 5.4e%s", pre, m[i*col_size + j], post);
       }

Now with the above change, rather than use " %5.4e" in many places, use a macro and string literal concatenation. Certainly easier to adjust one format than many.

      #define FMT_M "% 5.4e"
      ...
         // Many places 
         // printf("%5.4e%s", ...);
         printf("%s" FMT_M "%s", pre, m[i*col_size + j], post);

Recommend to use size_t for array indexing than int. int maybe insufficient with large arrays. Certainly not for small programs - but good coding practice.

// void print(fpoint_t* m, int row_size, int col_size) {
void print(fpoint_t* m, size_t row_size, size_t col_size) {

Add const. This allows for some compiler optimizations and lets the caller know *m is not changed.

// void print(fpoint_t* m, int row_size, int col_size) {
void print(const fpoint_t* m, int row_size, int col_size) {

printf() of a generic string is a problem should a "%" appear in it - maybe due to code maintenance or changes. Consider 1 of the 2 alternates - which likely generate the same code on a good compiler.

// printf("\n\t");
printf("%s", "\n\t");
// or 
fputs("\n\t", stdout);

Minor. Some compilers reserve ..._t identifiers. Consider non-_t names.

// typedef float fpoint_t;
typedef float fpoint_T;

A commented sample output would help to document coding goals

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.