Category : C Source Code
Archive   : CALC-TC!.ZIP
Filename : CALC.C

 
Output of file : CALC.C contained in archive : CALC-TC!.ZIP
/***************************************************************************/
/* A 10-Digit Calculator */
/* */
/* A program by Peter Roach - Compuserve 71620,506 */
/* */
/* Compiler : Turbo C - 1.0 */
/* */
/* This program emulates a 10-digit 4-function calculator, with a single */
/* memory, Square Root, and Log and AntiLog to base 10. */
/* */
/* The picture of the calculator may be located anywhere on the screen */
/* by changing the #defines for XPOS and YPOS to reflect the X and Y */
/* values of its top left corner. */
/* */
/* All calculator functions are activated by pressing the following keys: */
/* 0..9 and . - used to enter numbers. */
/* A - convert displayed number to its Antilog to base 10 */
/* L - convert displayed number to its Log to base 10 */
/* S - take the Square Root of the displayed number */
/* CA - Clear All */
/* CE - Clear Entry */
/* MC - Memory Clear */
/* MR - Memory Read */
/* M+ - Add to Memory */
/* M- - Subtract from Memory */
/* + - Add */
/* - - Subtract */
/* * - Multiply */
/* / - Divide */
/* = - Complete pending calculation */
/* Q - Quit the calculator */
/* The = function can also be performed by pressing the Enter key. */
/* */
/* The pending operation is shown to the right of the number, and an M is */
/* displayed to the left of the number if there is a number in the memory. */
/* */
/* If a math error occurs, this is indicated below the number, and a beep */
/* will be heard. In this case, the displayed number may not be valid. */
/* To clear an error, use CA, CE or Q. No other keys will be active until */
/* the error has been cleared. */
/* */
/* If the C or M key is pressed by mistake, pressing any key except the */
/* indicated ones will produce a beep and cancel the Clear or Memory */
/* function. */
/***************************************************************************/


#include
#include
#include
#include
#include
#include


#define TRUE 1
#define FALSE 0
#define XPOS 29
#define YPOS 7
#define BORDER 15
#define WHITE 15
#define BLACK 0


double dispv = 0; /* Real value of displayed number */
double stor = 0; /* Temporary store */
double mem = 0; /* The calculator's memory */
char disp[13] = "0."; /* The displayed number */
char pendop = ' '; /* The operation to be performed */
int errflag = FALSE; /* True if an error has occurred */
int newnum = TRUE; /* True if next number key should clear display */
int decpt = FALSE; /* True if . key has been pressed */
int primed = FALSE; /* True if next function key should execute
pending operation. */


void clrscr(int foregnd, int backgnd);
void gotoxy(int col, int row);
void beep(void);
void drawcalc(void);
void do_error(double errval);
char getkey(void);
void showresult(char last_op);
void do_num(char digit);
char *num_to_str(double num);
void do_alog(void);
void do_log(void);
void do_sqrt(void);
void do_math(char mathfunc);
void do_mem(char memfunc);
void do_clr(char clrfunc);


main()

{
char inkey ; /* Holds current keypress */

clrscr(WHITE, BLACK); /* Initialize display */
drawcalc();
do {
showresult(pendop);
inkey = getkey();
if (errflag) /* If error has occurred, only valid */
switch (inkey) { /* function is Clear */
case 'C' : showresult('C');
do_clr(getkey());
case 'Q' : break; /* if 'Q', drop to 'while' */
default : beep(); /* invalid keystroke */
}
else
switch (inkey) { /* if not error, all functions */
/* are available */
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' : do_num(inkey); break;
case '.' : if (!decpt)
decpt = TRUE; /* only accept one */
else
beep(); /* decimal point */
break; /* in a number */
case 'A' : do_alog(); break;
case 'L' : do_log(); break;
case 'S' : do_sqrt(); break;
case 'M' : showresult('M');
do_mem(getkey()); break;
case 'C' : showresult('C');
do_clr(getkey()); break;
case '+' :
case '-' :
case '*' :
case '/' :
case '=' : do_math(inkey);
case 'Q' : break; /* if 'Q', drop to 'while' */
default : beep(); /* invalid keystroke */
}
} while (inkey != 'Q'); /* break out of loop and quit if Q pressed */
gotoxy(1,25); /* Move cursor to bottom of screen */

} /* main */


void clrscr(int foregnd, int backgnd)
/* Clears screen */

{
union REGS reg;

reg.h.ah = 6; /* scroll */
reg.h.al = 0; /* blank window */
reg.x.cx = 0; /* from row 0, col 0 */
reg.x.dx = (24 << 8) + 79; /* to row 24, col 79 */
reg.h.bh = (backgnd << 4) + foregnd;
int86(0x10,®,®);

} /* clrscr */


void gotoxy(int col, int row)
/* Moves cursor to specific column and row - as Turbo Pascal */
/* Rows 1..25, Columns 1..80 */

{
union REGS reg;

reg.h.ah = 2;
reg.h.bh = 0;
reg.x.dx = ((row-1) << 8) + (col-1);
int86(0x10,®,®);

} /* gotoxy */


void beep()
/* Beep the speaker */

{
union REGS reg;

reg.h.ah = 14; /* write tty */
reg.h.al = 7; /* bell character */
reg.h.bl = 15; /* dummy foreground color */
int86(0x10,®,®);

} /* beep */


void drawcalc()
/* Draws the calculator */

{
int i;

gotoxy(XPOS,YPOS);
for (i=1; i<=22; i++)
putchar(BORDER);
gotoxy(XPOS,YPOS+1);
putchar(BORDER); cputs(" "); putchar(BORDER);
gotoxy(XPOS,YPOS+2);
putchar(BORDER); cputs(" "); putchar(BORDER);
gotoxy(XPOS,YPOS+3);
putchar(BORDER); cputs("--------------------"); putchar(BORDER);
gotoxy(XPOS,YPOS+4);
putchar(BORDER); cputs(" Log Quit / MC "); putchar(BORDER);
gotoxy(XPOS,YPOS+5);
putchar(BORDER); cputs(" Alog 7 8 9 * MR "); putchar(BORDER);
gotoxy(XPOS,YPOS+6);
putchar(BORDER); cputs(" Sqrt 4 5 6 - M- "); putchar(BORDER);
gotoxy(XPOS,YPOS+7);
putchar(BORDER); cputs(" CE 1 2 3 + M+ "); putchar(BORDER);
gotoxy(XPOS,YPOS+8);
putchar(BORDER); cputs(" CA 0 . = "); putchar(BORDER);
gotoxy(XPOS,YPOS+9);
putchar(BORDER); cputs(" "); putchar(BORDER);
gotoxy(XPOS,YPOS+10);
for (i=1; i<=22; i++)
putchar(BORDER);

} /* drawcalc */


void do_error(double errval)
/* Called when a math error occurs. errval is value to be displayed */

{
dispv = errval;
errflag = TRUE;
beep();

} /* do_error */


char getkey()
/* Returns uppercase value of one key from keyboard */

{

char ch;

while (kbhit())
ch = getch(); /* Clear kbd buff of garbage */
ch = getch(); /* read the key */
return(ch == 13 ? '=' : toupper(ch)); /* return = if Enter pressed */
/* else return upper of key */
} /* getkey */


void showresult(char last_op)
/* Called to display result of input or calculation. last_op is
the character to be displayed to the right of the number */

{
gotoxy(XPOS+2,YPOS+2);
if (mem != 0)
cputs("M ");
else
cputs(" ");
printf("%12s %c",disp,last_op);
gotoxy(XPOS+8,YPOS+3);
if (errflag)
cputs("Error");
else
cputs("-----");
gotoxy(XPOS+15,YPOS+2);

} /* showresult */


void do_num(char digit)
/* Process a number key */

{
char temp[2];

if (newnum) {
decpt = FALSE;
strcpy(disp,"0.");
newnum = FALSE;
primed = TRUE;
}
if (strlen(disp) < 11) {
if (decpt) {
temp[0] = digit;
temp[1] = NULL;
strcat(disp, temp); /* add char. on right */
} else {
if ((disp[0] == '0') && !decpt) /* remove leading */
strcpy(disp,&disp[1]); /* zero if >1 */
disp[strlen(disp)-1] = digit; /* last char = digit */
strcat(disp,"."); /* tack on a . */
}
dispv = atof(disp);
}
else beep();

} /* do_num */


char *num_to_str(double num)
/* Convert a number to a string */

{
char strng[32];
int lenstr;

sprintf(strng,"% 12.12f",num); /* convert num to string */
strncpy(strng,strng,12); /* truncate it to 12 chars */
strng[12] = NULL; /* and null terminate it */
lenstr = strlen(strng)-1;
while (strng[lenstr] == '0') { /* strip trailing zeros */
strncpy(strng,strng,lenstr);
strng[lenstr--] = NULL;
}
return(strng);

} /* num_to_str */


void do_alog()
/* Convert displayed number to its Antilog to base 10 */

{
if (fabs(dispv) > 9.99999)
do_error(0); /* only display 10 digits */
else
dispv = pow(10,dispv);
strcpy(disp,num_to_str(dispv));
newnum = TRUE;

} /* do_alog */


void do_log()
/* Convert displayed number to its Log to base 10 */

{
if (dispv <= 0)
do_error(0); /* invalid log of 0 or neg. number */
else
dispv = log10(dispv);
strcpy(disp,num_to_str(dispv));
newnum = TRUE;

} /* do_log */


void do_sqrt()
/* Convert displayed number to its Square Root */

{
if (dispv < 0)
do_error(sqrt(fabs(dispv))); /* no sqrt of neg. number */
else
dispv = sqrt(dispv);
strcpy(disp,num_to_str(dispv));
newnum = TRUE;

} /* do_sqrt */


void do_math(char mathfunc)
/* Process + - * / = keys. Also called to complete pending
calculation when M+ or M- is entered */

{
if (primed || (mathfunc == '=')) {
switch (pendop) {
case '+' : dispv = stor + dispv; break;
case '-' : dispv = stor - dispv; break;
case '*' : dispv = stor * dispv; break;
case '/' : if (dispv != 0)
dispv = stor / dispv;
else
do_error(0);
}
primed = FALSE;
newnum = TRUE;
}
switch (mathfunc) {
case '+':
case '-':
case '*':
case '/': pendop = mathfunc; break;
default : pendop = ' ';
}
stor = dispv;
strcpy(disp,num_to_str(dispv));
if (fabs(dispv) > 9999999999.0)
do_error(dispv); /* only 10 digits */

} /* do_math */


void do_mem(char memfunc)
/* Process memory functions MC, MR, M+ and M- */

{
switch (memfunc) {
case 'C' : mem = 0; break;
case 'R' : dispv = mem;
strcpy(disp,num_to_str(mem));
primed = TRUE;
break;
case '+' : do_math('=');
mem += dispv;
break;
case '-' : do_math('=');
mem -= dispv;
break;
default : beep();
}

} /* do_mem */


void do_clr(char clrfunc)
/* Process Clear functions CE and CA */

{
switch (clrfunc) {
case 'A' : primed = FALSE; /* do all for C A */
stor = 0;
mem = 0;
pendop = ' ';
decpt = FALSE;
case 'E' : newnum = TRUE; /* only from here for C E */
strcpy(disp,"0.");
dispv = 0;
errflag = FALSE;
break;
default : beep(); /* invalid keystroke */
}

} /* do_clr */


  3 Responses to “Category : C Source Code
Archive   : CALC-TC!.ZIP
Filename : CALC.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/