Datareign

A Simple Command Line Calculator

This is a useful little tool. It's a multi-function floating point calculator that can take the first part of its input from the environment, thus you can do something like:

      user_prompt> calc 349 / 3.45 | calc ^ 7

which will give the result…

      108403724648448.000000

I've found it helps in places where the integer-only 'eval' command doesn't meet the need.

Cut and paste the following code into a file called 'calc.c' then compile it with something like…

      cc calc.c -o calc.o -a calc

There's lots of improvements and additions you can make to this which can turn it into a very useful tool.

Code

 
  #include <stdio.h>
  #include <stdlib.h>
 
  usage()
  {
    printf("\nSimple floating point calculator\n");
    printf("----------------------------------\n\n");
    printf("Enter your query on the command line in the form...\n\n");
    printf("   calc <num1> <op> <num2>        (note the spaces)\n\n");
    printf("where num1 and num2 are numbers and 'op' may be...\n");
    printf("   +   adds the two numbers\n");
    printf("   -   Subtracts num2 from num1\n");
    printf("   x   multiplies the two numbers\n");
    printf("   /   divides num1 by num2\n");
    printf("   %%   finds the remainder from dividing num1 by num2");
    printf("   ^   raises num1 to the power of num2\n\n");
    printf("calc will return a floating point number.\n\n");
  }
 
  /* =============================================================== */
  /* Gets one word (delimited by a space) from the standard input... */
  /* =============================================================== */
  char *getword()
  {
    static char word[40];
    int wordlength = 0;
    int thischar;
 
    /* ------------------------------- */
    /* Strip off any leading spaces... */
    /* ------------------------------- */
    while((thischar = getchar()) != EOF
           && isascii(thischar)
           && isspace(thischar));
    /* ------------------- */
    /* Now get one word... */
    /* ------------------- */
    while(thischar != EOF
          && isascii(thischar)
          && !isspace(thischar))
    {
       if(wordlength < (sizeof(word) - 1))
          word[wordlength++] = thischar;
       thischar = getchar();
    }
    word[wordlength] = '0';
    return(wordlength == 0 && thischar == EOF ? NULL : word); 
  }
 
  /* ================================= */
  /* This is where it really starts... */
  /* ================================= */
  main(argc, argv)
  int argc;
  char *argv[];
  {
    float operand1, operand2;
    float result = 0;
    char operation;
    int counter;
    char *first = (char *)malloc(40);
    char *second = (char *)malloc(40);
    long longop1, longop2;
 
    /* ----------------------------------------- */
    /* Have we got two operands and an operator? */
    /* ----------------------------------------- */
    if(argc < 4)
    {
       /* -------------------------------- */
       /* NO: Try reading from stdin       */
       /*     in case num1 is in a pipe... */
       /* -------------------------------- */
       if(argc > 2)
       {
          free(first);
          if((first = getword()) != NULL)
          {
             operation = (char)*argv[1];
             sprintf(second, "%s", argv[2]);
          }
          else
          {
            usage();
            exit(1);
          }
       }
       else
       {
          usage();
          exit(1);
       }
    }
    else
    {
       /* --------------------------------------- */
       /* 3 parameters: assume 1st is a number... */
       /* --------------------------------------- */
       sprintf(first, "%s", argv[1]);
       operation = (char)*argv[2];
       sprintf(second, "%s", argv[3]);
    }
 
    /* ------------------------------------------- */
    /* Put the parameters into usable variables... */
    /* ------------------------------------------- */
    operand1 = atof(first);
    operand2 = atof(second);
 
   /* Perform the calculation */
   switch(operation)
  {
    case '+':
    result = operand1 + operand2;
    break;
 
    case '-':
    result = operand1 - operand2;
    break;
 
    case 'x':
    result = operand1 * operand2;
    break;
 
    case '/':
    if (operand2 != 0) result = operand1 / operand2;
    else printf("Divide by 0 error!\n");
    break;
 
    case '%':
    if (operand2 != 0)
    {
      longop1 = (long)operand1;
      longop2 = (long)operand2;
      result = (float)(longop1 % longop2);
    }
    else
    {
      printf("Divide by 0 error!\n");
    }
    break;
 
    case '^':
    result = operand1;
    longop2 = (long)operand2;
    for (counter = 2;
         counter < longop2 + 1;
         counter++)
         result = operand1 * result;
    break;
 
    default:
    printf("Invalid operation!\n");
    break;
  }
 
  /* Print out the result */
  printf("%f\n", result);
Last modified: 2009/04/04 22:23