5
\$\begingroup\$

I've recently started programming in C and as my first serious program I thought I'd create a simple calculator. To make it a bit more complex I decided not to use the functions included in math.h (like pow) but to create these functions by myself. Let me know if there is something I can do to improve this code.

#include<stdio.h>


double power(double x, double y, double r)                                                       // This function calculates the power and takes numer1, number2 and the results
{
    r = 1;                                                                           // We need to initialize the results otherwise we can't store the partial result on line 11
    int c;  
    for (c = y; c > 0; c--)                                  // putting c equal to y we can decrement c and obtain the precise number of operations needed to complete the power
    { 
        int pow = y;                                  // that's a bit tricky: we can't apply the modulus operand in line 12 because y is a double, so we must convert y in an int 
        r *= x;                                                             // this way result = 1 * number1, then number1 * number1, then number1 * number1 * number1 and so on
        if ((x < 0) && (pow % 2 == 1))    /* If the first number is negative, and we calculate the power of this number to 2 or multiples, the number resulting will be negative
                                                                to obtain the correct result (positive) we must multiply the result to -1, if the previous conditions are met */
        {
            x *= -1;
        }
    }
    printf("%0.1lf", r);
}


double root(double x, double y, double r)
{
    int c;
      if (x < 0)
      {
         puts("is impossible to calcultate the root of a negative number");
      }
    for (c = 1; c < x; c++)
    {
        int partRes = x;
        partRes /= c;
        if (partRes * partRes == x)
        {
            printf("The root of %0.1lf is: %0.1d\n", x, partRes);
            break;
        }
    }
}


int main()
{
    double num1, num2, res;
    char op;
    puts("Input number, operator and number");
    puts("operands permitted: + (addition), - (subtraction), * (multiplication), / (division), ^ (power), $ (square root)");
    scanf("%lf %c %lf", &num1, &op, &num2);
    if (op == '+')
    {
        res = num1 + num2;
        printf("%0.1lf", res);
    }
    else if (op == '-')
    {
        res = num1 - num2;
        printf("%0.1lf", res);
    }
    else if (op == '*')
    {
        res = num1 * num2;
        printf("%0.1lf", res);
    }
    else if (op == '/')
    {
        res = num1 / num2;
        printf("%0.1lf", res);
    }
    else if (op == '^')
    {
        power(num1, num2, res);
    }
    else if (op == '$')
    {
        root(num1, num2, res);
    }
    else 
    printf("error, use a valid operand");
}
\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

power() problems

double power() does not return a value.

Incorrect result when y is not a value in the int range.

Code attempts a linear power calculation: O(y). Research Exponentiation by squaring. It is faster and less precision loss.

double r parameter serves no purpose. Instead make a local double r variable.

A floating point power function is one of the most changeling functions to code well. Rough cut below.


root() problems

double root() does not return a value.

Other problems like power().


It floating point, not fixed point

More informative to use exponential notation for large and small value than a fix-point format.

// printf("%0.1lf", res);
printf("%g", res);

Sample improved my_power() - unchecked

// Very rough code
double my_power(double x, double y) {
  double whole;
  double fraction = modf(y, &whole);
  if (fraction == 0.0) {
    double r = 1.0;
    double p = fabs(whole);
    while (p > 0) {
      if (fmod(p, 2.0)) {
        r *= x;
      }
      x *= x;
      p /= 2.0;
    }
    if (whole < 0) {
      r = 1.0 / r;
    }
    return r;
  }
  if (x == 0.0) {
    return 0.0;
  }
  if (x < 0.0) {
    return NAN;
  }
  return exp(log(x) * y);
}
\$\endgroup\$

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.