1
\$\begingroup\$

I made a calculator in C without #include. Now, I want to make my code shorter and better. But I don't know how.

Here is my code:

int printf(const char *format, ...);
extern int scanf(const char *format, ...);
double pow(double x, double y);

int main()
{
    do
    {
        double num1;
        double a, b = 1;
        char ch1;
        float r;
        scanf("%lf", &num1);
        printf("\ta - Factorial\n\tb - Continue\n");
        scanf(" %c", &ch1);
        switch (ch1)
        {
            case 'a':
                for (a = 1; a <= num1; a++)
                {
                    b = b * a;
                }
                if (b < 500000001 & num1 > 0)
                {
                    printf("%f\n", b);
                }
                else
                {
                    if (b > 500000000)
                    {
                        printf("Number is Big\n");
                    }
                    if (num1 < 1)
                    {
                        printf("Number is Small\n");
                    }
                }
                break;
            case 'b':
                double num2;
                char ch2;
                scanf("%lf", &num2);
                printf("\ta - Add\n\tb - Substract\n\tc - Multiply\n\td - Divide\n\te - Power\n\tf - Radical\n");
                scanf(" %c", &ch2);
                switch (ch2)
                {
                    case 'a':
                        r = num1 + num2;
                        if (num1 + num2 < 500000001 & num1 + num2 > -500000001 & num1 - num2 < 500000001 & num2 - num1 < 500000001)
                        {
                            printf("%lf + %lf = %f\n", num1, num2, r);
                        }
                        else if (num1 + num2 > 500000000)
                        {
                            printf("Number is Big\n");
                        }
                        break;
                    case 'b':
                        r = num1 - num2;
                        if (num1 + num2 < 500000001 & num1 + num2 > -500000001 & num1 - num2 < 500000001 & num2 - num1 < 500000001)
                        {
                            printf("%lf - %lf = %f\n", num1, num2, r);
                        }
                        else if (num1 + num2 > 500000000)
                        {
                            printf("Number is Big\n");
                        }
                        break;
                    case 'c':
                        r = num1 * num2;
                        if (num1 * num2 < 500000001 & num1 * num2 > -500000001)
                        {
                            printf("%lf * %lf = %f\n", num1, num2, r);
                        }
                        else
                        {
                            if (num1 * num2 > 500000000)
                            {
                                printf("Number is Big\n");
                            }
                            if (num1 * num2 < -500000000)
                            {
                                printf("Number is Small\n");
                            }
                        }
                        break;
                    case 'd':
                        r = num1 / num2;
                        if (num1 * num2 < 500000001 & num1 * num2 > -500000001 && num2 > 0 | num1 == 0 & num2 != 0)
                        {
                            printf("%lf / %lf = %f\n", num1, num2, r);
                        }
                        else
                        {
                            if (num1 * num2 > 500000000)
                            {
                                printf("Number is Big\n");
                            }
                            if (num1 * num2 < -500000000)
                            {
                                printf("Number is Small\n");
                            }
                            if (num1 > 0 & num2 == 0 | num1 == 0 & num2 == 0)
                            {
                                printf("Undefined\n");
                            }
                        }
                        break;
                    case 'e':
                        r = pow(num1, num2);
                        if (pow(num1, num2) < 500000001 & pow(num1, num2) > -500000001)
                        {
                            printf("%lf ^ %lf = %f\n", num1, num2, r);
                        }
                        else
                        {
                            if (pow(num1, num2) > 500000000)
                            {
                                printf("Number is Big\n");
                            }
                            if (pow(num1, num2) > -500000000)
                            {
                                printf("Number is Small\n");
                            }
                        }
                    case 'f':
                        r = pow(num1, 1 / num2);
                        if (pow(num1, num2) < 500000001 & pow(num1, num2) > -500000001)
                        {
                            printf("%lf √ %lf = %f\n", num1, num2, r);
                        }
                        else
                        {
                            if (pow(num1, num2) > 500000000)
                            {
                                printf("Number is Big\n");
                            }
                            if (pow(num1, num2) > -500000000)
                            {
                                printf("Number is Small\n");
                            }
                        }
                        break;
                    default:
                        printf("Invalid\n");
                }
                break;
        }
    }
    while (1);
}
\$\endgroup\$
3
  • 7
    \$\begingroup\$ Two questions, if I may: Why avoid #include and what is the deal with 500000000 and similar randomly sprinkled throughout the code? \$\endgroup\$
    – Lev M.
    Dec 5, 2020 at 19:11
  • 1
    \$\begingroup\$ Another question: why is scanf() extern but printf() and pow() aren't? \$\endgroup\$
    – AJNeufeld
    Dec 7, 2020 at 4:58
  • 2
    \$\begingroup\$ Unless this is for some "code golf" challenge, then shorter is not necessarily better. \$\endgroup\$
    – Lundin
    Dec 11, 2020 at 13:19

1 Answer 1

1
\$\begingroup\$

I made a calculator in C without #include. Now, I want to make my code shorter and better.

To make the code better

Focus on clarity and not shortness.

Use #include<>s.

Check return values from input functions.

Replace naked magic numbers:

// if (b > 500000000)
// if (num1 * num2 < 500000001 

#define LIMIT 500000000
...
if (b > LIMIT)
if (num1 * num2 <= LIMIT  /* not quite the same with FP math, but certainly matches intent */

Use && instead of & for logical tests.

Remove redundant code

// r = num1 + num2;
// if (num1 + num2 < 500000001 & num1 + num2 > -500000001 & num1 - num2 < 500000001 & num2 - num1 < 500000001)

r = num1 + num2;
if (r <= LIMIT && r >= -LIMIT)

Even better, consider a helper function for the range test.

r = num1 + num2;
if (in_range(r))

More informative to print double with "%g" than "%f".

Review potential bug in case 'd':. Why if (num1 * num2 instead of if (num1 / num2?

Prevent division by 0.

Very unclear why code uses float r; with its differing precision and range versus double r; here.


To make shorter

Keep in mind shorter is not certainly better.

Drop extern from extern int scanf(const char *format, ...);

Drop identifiers in prototypes: int scanf(const char *, ...);

Use #include<>s, less text in this .c file than adding your own prototypes.

Replace naked magic numbers.

b = b * a; --> b *= a;

Indent less. Use a tighter format: e.g.:

//            if (num1 < 1)
//                {
//                   printf("Number is Small\n");
//                }

if (num1 < 1) printf("Number is Small\n");

Replace simply prints

// printf("Number is Small\n");
puts("Number is Small");

Replace do

//do
//  {
//  } while (1);

for (;;) { }

l not needed.

//printf("%lf - %lf = %f\n", num1, num2, r);
printf("%f - %f = %f\n", num1, num2, r);

Declare compare types on same line

    // double num1;
    // double a, b = 1;
    double num1, a, b = 1;

I'd re-use code per case

void print_result(double a, double b, double r, char op) {
  if (r >= -LIMIT && r <= LIMIT) {
    printf("%g %c %g = %g\n", num1, op, num2, r);
  } else {
    printf("Number is Big\n");
  }
}

    case 'a': print_result(a, b, a+b, '+'); break;
    case 'b': print_result(a, b, a-b, '-'); break;
    case 'c': print_result(a, b, a*b, '*'); break;
    ....

Look to code golf

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Unless I mistake your intent, Focus on clarity and not shortness and Look to code golf seem at odds? \$\endgroup\$
    – Reinderien
    Dec 11, 2020 at 17:24
  • 1
    \$\begingroup\$ @Reinderien Yes, parts of OP's 2 goals of "make the code better" are at odds with "To make shorter". With real world coding, it is striking a balance (mostly in favor of better) than making it shorter. \$\endgroup\$ Dec 11, 2020 at 17:28

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.