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.
#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);