math.c revision 12e1d9cb
112e1d9cbSmrg/*
24d9b34d9Smrg *  math.c  -  mathematics functions for a hand calculator under X
34d9b34d9Smrg *
44d9b34d9Smrg *  Author:    John H. Bradley, University of Pennsylvania
54d9b34d9Smrg *                (bradley@cis.upenn.edu)
64d9b34d9Smrg *                     March, 1987
74d9b34d9Smrg *
84d9b34d9Smrg *  RPN mode added and port to X11 by Mark Rosenstein, MIT Project Athena
94d9b34d9Smrg *
104d9b34d9Smrg *  Modified to be a client of the Xt toolkit and the Athena widget set by
114d9b34d9Smrg *  Donna Converse, MIT X Consortium.  This is all that remains of the
124d9b34d9Smrg *  original calculator, and it still needs to be rewritten.  The HP
134d9b34d9Smrg *  functionality should be separated from the TI functionality.
144d9b34d9Smrg *  Beware the HP functions: there are still errors here.
154d9b34d9Smrg *
164d9b34d9Smrg *  Geoffrey Coram fixed most of the HP mode bugs.
174d9b34d9Smrg */
184d9b34d9Smrg
194d9b34d9Smrg#include "xcalc.h"
204d9b34d9Smrg
214d9b34d9Smrg#ifdef _CRAY		/* kludge around Cray STDC compiler */
224d9b34d9Smrgdouble (*log_p)() = log;
234d9b34d9Smrg#define log ((*log_p))
244d9b34d9Smrgdouble (*exp_p)() = exp;
254d9b34d9Smrg#define exp ((*exp_p))
264d9b34d9Smrgdouble (*sqrt_p)() = sqrt;
274d9b34d9Smrg#define sqrt ((*sqrt_p))
284d9b34d9Smrgdouble (*log10_p)() = log10;
294d9b34d9Smrg#define log10 ((*log10_p))
304d9b34d9Smrgdouble (*atan2_p)() = atan2;
314d9b34d9Smrg#define atan2 ((*atan2_p))
324d9b34d9Smrgdouble (*asin_p)() = asin;
334d9b34d9Smrg#define asin ((*asin_p))
344d9b34d9Smrgdouble (*acos_p)() = acos;
354d9b34d9Smrg#define acos ((*acos_p))
364d9b34d9Smrgdouble (*atan_p)() = atan;
374d9b34d9Smrg#define atan ((*atan_p))
384d9b34d9Smrgdouble (*sin_p)() = sin;
394d9b34d9Smrg#define sin ((*sin_p))
404d9b34d9Smrgdouble (*cos_p)() = cos;
414d9b34d9Smrg#define cos ((*cos_p))
424d9b34d9Smrgdouble (*tan_p)() = tan;
434d9b34d9Smrg#define tan ((*tan_p))
444d9b34d9Smrgdouble (*pow_p)() = pow;
454d9b34d9Smrg#define pow ((*pow_p))
464d9b34d9Smrg#endif /* _CRAY */
474d9b34d9Smrg
484d9b34d9Smrg#ifndef PI		/* sometimes defined in math.h */
494d9b34d9Smrg#define PI          3.14159265358979
504d9b34d9Smrg#endif
514d9b34d9Smrg#define E           2.71828182845904
524d9b34d9Smrg#define MAXDISP     11
534d9b34d9Smrg#define DEG 0		/* DRG mode.  used for trig calculations */
544d9b34d9Smrg#define RAD 1
554d9b34d9Smrg#define GRAD 2
564d9b34d9Smrg#define min(a,b) ((a) < (b) ? (a) : (b))
574d9b34d9Smrg#define max(a,b) ((a) > (b) ? (a) : (b))
584d9b34d9Smrg#define True	1
594d9b34d9Smrg#define False   0
604d9b34d9Smrg
614d9b34d9Smrg#ifndef IEEE
628512f934Smrgjmp_buf env;
634d9b34d9Smrg#endif
644d9b34d9Smrg
654d9b34d9Smrg
664d9b34d9Smrg/* This section is all of the state machine that implements the calculator
674d9b34d9Smrg * functions.  Much of it is shared between the infix and rpn modes.
684d9b34d9Smrg */
694d9b34d9Smrg
708512f934Smrgstatic int flagINV, flagPAREN, flagM, drgmode;	/* display flags */
714d9b34d9Smrg
724d9b34d9Smrgstatic double drg2rad=PI/180.0;  /* Conversion factors for trig funcs */
734d9b34d9Smrgstatic double rad2drg=180.0/PI;
744d9b34d9Smrgstatic int entered=1;  /* true if display contains a valid number.
754d9b34d9Smrg                          if==2, then use 'dnum', rather than the string
764d9b34d9Smrg                          stored in the display.  (for accuracy)
774d9b34d9Smrg                          if==3, then error occurred, only CLR & AC work */
784d9b34d9Smrg/* entered seems to be overloaded - dmc */
794d9b34d9Smrgstatic int lift_enabled = 0;	/* for rpn mode only */
804d9b34d9Smrg
814d9b34d9Smrgstatic int CLR    =0;  /* CLR clears display.  if 1, clears acc, also */
824d9b34d9Smrgstatic int Dpoint=0;  /* to prevent using decimal pt twice in a # */
834d9b34d9Smrgstatic int clrdisp=1;  /* if true clears display before entering # */
844d9b34d9Smrgstatic int lastop =kCLR;
854d9b34d9Smrgstatic int memop  =kCLR;
864d9b34d9Smrgstatic int exponent=0;
874d9b34d9Smrgstatic double acc =0.0;
884d9b34d9Smrgstatic double dnum=0.0;
894d9b34d9Smrg#define XCALC_MEMORY 10
904d9b34d9Smrgstatic double mem[XCALC_MEMORY] = { 0.0 };
914d9b34d9Smrg
924d9b34d9Smrgstatic void   DrawDisplay(void);
934d9b34d9Smrgstatic void   PushOp(int op);
944d9b34d9Smrgstatic int    PopOp(void);
954d9b34d9Smrgstatic int    isopempty(void);
964d9b34d9Smrg#ifdef DEBUG
974d9b34d9Smrgstatic void   showstack(char *string);
984d9b34d9Smrg#endif
994d9b34d9Smrgstatic void   PushNum(double num);
1004d9b34d9Smrgstatic double PopNum(void);
1014d9b34d9Smrgstatic void   RollNum(int dir);
1024d9b34d9Smrgstatic void   ClearStacks(void);
1034d9b34d9Smrgstatic int    priority(int op);
1044d9b34d9Smrg
1054d9b34d9Smrg/*
1064d9b34d9Smrg * The following is to deal with the unfortunate assumption that if errno
1074d9b34d9Smrg * is non-zero then an error has occurred.  On some systems (e.g. Ultrix),
1084d9b34d9Smrg * sscanf will call lower level routines that will set errno.
1094d9b34d9Smrg */
1104d9b34d9Smrg
1114d9b34d9Smrgstatic void
1128512f934Smrgparse_double (char *src, char *fmt, double *dp)
1134d9b34d9Smrg{
1144d9b34d9Smrg    int olderrno = errno;
1154d9b34d9Smrg
1164d9b34d9Smrg    (void) sscanf (src, fmt, dp);
1174d9b34d9Smrg    errno = olderrno;
1184d9b34d9Smrg    return;
1194d9b34d9Smrg}
1204d9b34d9Smrg
1214d9b34d9Smrg
1224d9b34d9Smrg/*********************************/
1238512f934Smrgint pre_op(int keynum)
1244d9b34d9Smrg{
1254d9b34d9Smrg    if (keynum==-1) return(0);
1264d9b34d9Smrg
1274d9b34d9Smrg    errno = 0;			/* for non-IEEE machines */
1284d9b34d9Smrg
1294d9b34d9Smrg    if ( (entered==3) && !(keynum==kCLR || keynum==kOFF)) {
1304d9b34d9Smrg      if (rpn) {
1314d9b34d9Smrg	clrdisp++;
1324d9b34d9Smrg      } else {
1334d9b34d9Smrg        ringbell();
1344d9b34d9Smrg        return(1);	/* the intent was probably not to do the operation */
1354d9b34d9Smrg      }
1364d9b34d9Smrg    }
1374d9b34d9Smrg
1384d9b34d9Smrg    if (keynum != kCLR) CLR=0;
1394d9b34d9Smrg    return(0);
1404d9b34d9Smrg}
1414d9b34d9Smrg
1424d9b34d9Smrg#ifndef IEEE
1434d9b34d9Smrg
1444d9b34d9Smrg/* cannot assign result of setjmp under ANSI C, use global instead */
1454d9b34d9Smrgstatic volatile int SignalKind;
1464d9b34d9Smrg
1478512f934Smrgvoid fail_op(void)
1484d9b34d9Smrg{
1494d9b34d9Smrg    if (SignalKind == SIGFPE)
1508512f934Smrg	strcpy(dispstr, "math error");
1518512f934Smrg    else if (SignalKind == SIGILL)
1528512f934Smrg	strcpy(dispstr, "illegal operand");
1534d9b34d9Smrg
1544d9b34d9Smrg    entered=3;
1554d9b34d9Smrg    DrawDisplay();
1564d9b34d9Smrg    return;
1574d9b34d9Smrg}
1584d9b34d9Smrg
1594d9b34d9Smrg/*ARGSUSED*/
1608512f934Smrgsignal_t fperr(int sig)
1614d9b34d9Smrg{
1624d9b34d9Smrg#if defined(SYSV) || defined(SVR4) || defined(linux)
1638512f934Smrg    signal(SIGFPE, fperr);
1644d9b34d9Smrg#endif
1654d9b34d9Smrg    SignalKind = sig;
1664d9b34d9Smrg    longjmp(env,1);
1674d9b34d9Smrg}
1684d9b34d9Smrg
1694d9b34d9Smrg/* for VAX BSD4.3 */
1704d9b34d9Smrg/*ARGSUSED*/
1718512f934Smrgsignal_t illerr(int sig)
1724d9b34d9Smrg{
1734d9b34d9Smrg    /* not reset when caught? */
1748512f934Smrg    signal(SIGILL, illerr);
1754d9b34d9Smrg
1764d9b34d9Smrg    SignalKind = sig;
1774d9b34d9Smrg    longjmp(env,1);
1784d9b34d9Smrg}
1794d9b34d9Smrg
1804d9b34d9Smrg#endif	/* not IEEE */
1814d9b34d9Smrg
1824d9b34d9Smrg
1838512f934Smrgvoid post_op(void)
1844d9b34d9Smrg{
1854d9b34d9Smrg#ifdef DEBUG
1864d9b34d9Smrg    showstack("\0");
1874d9b34d9Smrg#endif
1884d9b34d9Smrg#ifndef IEEE
1894d9b34d9Smrg    if (errno) {
1904d9b34d9Smrg        strcpy(dispstr,"error");
1914d9b34d9Smrg        DrawDisplay();
1924d9b34d9Smrg        entered=3;
1934d9b34d9Smrg        errno=0;
1944d9b34d9Smrg        }
1954d9b34d9Smrg#endif
1964d9b34d9Smrg}
1974d9b34d9Smrg/*-------------------------------------------------------------------------*/
1984d9b34d9Smrgstatic void
1994d9b34d9SmrgDrawDisplay(void)
2004d9b34d9Smrg{
2014d9b34d9Smrg    if ((int) strlen(dispstr) > 12) {	 /* strip out some decimal digits */
2024d9b34d9Smrg        char tmp[32];
2034d9b34d9Smrg        char *estr = index(dispstr,'e');  /* search for exponent part */
2044d9b34d9Smrg        if (!estr) dispstr[12]='\0';      /* no exp, just trunc. */
2054d9b34d9Smrg        else {
2064d9b34d9Smrg            if ((int) strlen(estr) <= 4)
2074d9b34d9Smrg                sprintf(tmp,"%.8s",dispstr); /* leftmost 8 chars */
2084d9b34d9Smrg            else
2094d9b34d9Smrg                sprintf(tmp,"%.7s",dispstr); /* leftmost 7 chars */
2104d9b34d9Smrg            strcat (tmp,estr);            /* plus exponent */
2114d9b34d9Smrg            strcpy (dispstr,tmp);
2124d9b34d9Smrg            }
2134d9b34d9Smrg        }
2144d9b34d9Smrg    draw(dispstr);
2154d9b34d9Smrg    setflag(XCalc_MEMORY, (flagM));
2164d9b34d9Smrg    setflag(XCalc_INVERSE, (flagINV));
2174d9b34d9Smrg    setflag(XCalc_DEGREE, (drgmode==DEG));
2184d9b34d9Smrg    setflag(XCalc_RADIAN, (drgmode==RAD));
2194d9b34d9Smrg    setflag(XCalc_GRADAM, (drgmode==GRAD));
2204d9b34d9Smrg    setflag(XCalc_PAREN, (flagPAREN));
2214d9b34d9Smrg}
2224d9b34d9Smrg
2234d9b34d9Smrg/*-------------------------------------------------------------------------*/
2244d9b34d9Smrgvoid
2258512f934Smrgnumeric(int keynum)
2264d9b34d9Smrg{
2274d9b34d9Smrg    char	st[2];
2284d9b34d9Smrg    int		cell = 0;
2294d9b34d9Smrg
2304d9b34d9Smrg  flagINV=0;
2314d9b34d9Smrg
2324d9b34d9Smrg  if (rpn && (memop == kSTO || memop == kRCL || memop == kSUM)) {
2334d9b34d9Smrg      switch (keynum) {
2344d9b34d9Smrg	case kONE:	cell = 1; break;
2354d9b34d9Smrg	case kTWO:	cell = 2; break;
2364d9b34d9Smrg	case kTHREE:	cell = 3; break;
2374d9b34d9Smrg	case kFOUR:	cell = 4; break;
2384d9b34d9Smrg	case kFIVE:	cell = 5; break;
2394d9b34d9Smrg	case kSIX:	cell = 6; break;
2404d9b34d9Smrg	case kSEVEN:	cell = 7; break;
2414d9b34d9Smrg	case kEIGHT:	cell = 8; break;
2424d9b34d9Smrg	case kNINE:	cell = 9; break;
2434d9b34d9Smrg	case kZERO:	cell = 0; break;
2444d9b34d9Smrg      }
2454d9b34d9Smrg      switch (memop) {
2464d9b34d9Smrg      case kSTO:
2474d9b34d9Smrg	mem[cell] = dnum;
2484d9b34d9Smrg	lift_enabled = 1;
2494d9b34d9Smrg	entered = 2;
2504d9b34d9Smrg	clrdisp++;
2514d9b34d9Smrg	break;
2524d9b34d9Smrg      case kRCL:
2534d9b34d9Smrg	PushNum(dnum);
2544d9b34d9Smrg	dnum = mem[cell];
2554d9b34d9Smrg	sprintf(dispstr, "%.8g", dnum);
2564d9b34d9Smrg	lift_enabled = 1;
2574d9b34d9Smrg        entered = 1;
2584d9b34d9Smrg	clrdisp++;
2594d9b34d9Smrg	break;
2604d9b34d9Smrg      case kSUM:
2614d9b34d9Smrg	mem[cell] += dnum;
2624d9b34d9Smrg	lift_enabled = 1;
2634d9b34d9Smrg	entered = 2;
2644d9b34d9Smrg	clrdisp++;
2654d9b34d9Smrg	break;
2664d9b34d9Smrg      }
2674d9b34d9Smrg      memop = kCLR;
2684d9b34d9Smrg      DrawDisplay();
2694d9b34d9Smrg      return;
2704d9b34d9Smrg  }
2714d9b34d9Smrg
2724d9b34d9Smrg  if (clrdisp) {
2734d9b34d9Smrg    dispstr[0]='\0';
2744d9b34d9Smrg    exponent=Dpoint=0;
2754d9b34d9Smrg/*    if (rpn && entered==2)
2764d9b34d9Smrg      PushNum(dnum);
2774d9b34d9Smrg */
2784d9b34d9Smrg    if (rpn & lift_enabled)
2794d9b34d9Smrg	PushNum(dnum);
2804d9b34d9Smrg  }
2814d9b34d9Smrg  if ((int) strlen(dispstr) >= MAXDISP)
2824d9b34d9Smrg    return;
2834d9b34d9Smrg
2844d9b34d9Smrg    switch (keynum){
2854d9b34d9Smrg      case kONE:	st[0] = '1'; break;
2864d9b34d9Smrg      case kTWO:	st[0] = '2'; break;
2874d9b34d9Smrg      case kTHREE:	st[0] = '3'; break;
2884d9b34d9Smrg      case kFOUR:	st[0] = '4'; break;
2894d9b34d9Smrg      case kFIVE:	st[0] = '5'; break;
2904d9b34d9Smrg      case kSIX:	st[0] = '6'; break;
2914d9b34d9Smrg      case kSEVEN:	st[0] = '7'; break;
2924d9b34d9Smrg      case kEIGHT:	st[0] = '8'; break;
2934d9b34d9Smrg      case kNINE:	st[0] = '9'; break;
2944d9b34d9Smrg      case kZERO:	st[0] = '0'; break;
2954d9b34d9Smrg    }
2964d9b34d9Smrg    st[1] = '\0';
2974d9b34d9Smrg    strcat(dispstr,st);
2984d9b34d9Smrg
2994d9b34d9Smrg  DrawDisplay();
3004d9b34d9Smrg  if (clrdisp && keynum != kZERO)
3014d9b34d9Smrg    clrdisp=0; /*no leading 0s*/
3024d9b34d9Smrg  memop = keynum;
3034d9b34d9Smrg  entered=1;
3044d9b34d9Smrg  lift_enabled = 0;
3054d9b34d9Smrg}
3064d9b34d9Smrg
3074d9b34d9Smrgvoid
3084d9b34d9Smrgbkspf(void)
3094d9b34d9Smrg{
3104d9b34d9Smrg
3114d9b34d9Smrg  lift_enabled = 0;
3124d9b34d9Smrg
3134d9b34d9Smrg  if (! flagINV)
3144d9b34d9Smrg  {
3154d9b34d9Smrg      if (entered!=1) {
3164d9b34d9Smrg	  clearf();
3174d9b34d9Smrg	  return;
3184d9b34d9Smrg      }
3194d9b34d9Smrg      if (clrdisp)
3204d9b34d9Smrg	  return;
3214d9b34d9Smrg      if ((int) strlen(dispstr) > 0) {
3224d9b34d9Smrg#ifndef X_LOCALE
3234d9b34d9Smrg          const char *dp = localeconv()->decimal_point;
3244d9b34d9Smrg          size_t dp_len = strlen(dp);
3254d9b34d9Smrg          size_t ds_len = strlen(dispstr);
3264d9b34d9Smrg          if (ds_len >= dp_len && strcmp(dispstr + ds_len - dp_len, dp) == 0)
3274d9b34d9Smrg             Dpoint=0;
3284d9b34d9Smrg#else
3294d9b34d9Smrg	  if (dispstr[strlen(dispstr)-1] == '.')
3304d9b34d9Smrg             Dpoint=0;
3314d9b34d9Smrg#endif
3324d9b34d9Smrg	  dispstr[strlen(dispstr)-1] = 0;
3334d9b34d9Smrg      }
3344d9b34d9Smrg      if (strlen(dispstr) == 0) {
3354d9b34d9Smrg	  strcat(dispstr, "0");
3364d9b34d9Smrg	  clrdisp++;
3374d9b34d9Smrg      }
3384d9b34d9Smrg  }
3394d9b34d9Smrg  else
3404d9b34d9Smrg  {
3414d9b34d9Smrg      strcpy(dispstr, "0");
3424d9b34d9Smrg      dnum = 0.0;
3434d9b34d9Smrg      clrdisp++;
3444d9b34d9Smrg      flagINV = 0;
3454d9b34d9Smrg  }
3464d9b34d9Smrg  DrawDisplay();
3474d9b34d9Smrg}
3484d9b34d9Smrg
3494d9b34d9Smrgvoid
3504d9b34d9Smrgdecf(void)
3514d9b34d9Smrg{
3524d9b34d9Smrg  flagINV=0;
3534d9b34d9Smrg  if (clrdisp) {
3544d9b34d9Smrg      if (rpn && lift_enabled)
3554d9b34d9Smrg	PushNum(dnum);
3564d9b34d9Smrg      strcpy(dispstr,"0");
3574d9b34d9Smrg  }
3584d9b34d9Smrg  if (!Dpoint) {
3594d9b34d9Smrg#ifndef X_LOCALE
3604d9b34d9Smrg    strcat(dispstr, localeconv()->decimal_point);
3614d9b34d9Smrg#else
3624d9b34d9Smrg    strcat(dispstr, ".");
3634d9b34d9Smrg#endif
3644d9b34d9Smrg    DrawDisplay();
3654d9b34d9Smrg    Dpoint++;
3664d9b34d9Smrg  }
3674d9b34d9Smrg  clrdisp=0;
3684d9b34d9Smrg  entered=1;
3694d9b34d9Smrg}
3704d9b34d9Smrg
3714d9b34d9Smrgvoid
3724d9b34d9Smrgeef(void)
3734d9b34d9Smrg{
3744d9b34d9Smrg  flagINV=0;
3754d9b34d9Smrg  if (clrdisp) {
3764d9b34d9Smrg      if (rpn && lift_enabled)
3774d9b34d9Smrg	PushNum(dnum);
3784d9b34d9Smrg      strcpy(dispstr, rpn ? "1" : "0");
3794d9b34d9Smrg  }
3804d9b34d9Smrg  if (!exponent) {
3814d9b34d9Smrg    strcat(dispstr,"E+");
3824d9b34d9Smrg    DrawDisplay();
3834d9b34d9Smrg    exponent=strlen(dispstr)-1;  /* where the '-' goes */
3844d9b34d9Smrg  }
3854d9b34d9Smrg  clrdisp=0;
3864d9b34d9Smrg  entered=1;
3874d9b34d9Smrg}
3884d9b34d9Smrg
3894d9b34d9Smrgvoid
3904d9b34d9Smrgclearf(void)
3914d9b34d9Smrg{
3924d9b34d9Smrg  flagINV=0;
3934d9b34d9Smrg  if (CLR && !rpn) { /* clear all */
3944d9b34d9Smrg    ClearStacks();
3954d9b34d9Smrg    flagPAREN=0;
3964d9b34d9Smrg  }
3974d9b34d9Smrg  CLR++;
3984d9b34d9Smrg  exponent=Dpoint=0;
3994d9b34d9Smrg  clrdisp=1;
4004d9b34d9Smrg  entered=1;
4014d9b34d9Smrg  strcpy(dispstr,"0");
4024d9b34d9Smrg  DrawDisplay();
4034d9b34d9Smrg}
4044d9b34d9Smrg
4054d9b34d9Smrgvoid
4064d9b34d9Smrgnegf(void)
4074d9b34d9Smrg{
4084d9b34d9Smrg  flagINV=0;
4094d9b34d9Smrg  if (exponent) {       /* neg the exponent */
4104d9b34d9Smrg    if (dispstr[exponent]=='-')
4114d9b34d9Smrg      dispstr[exponent]='+';
4124d9b34d9Smrg    else
4134d9b34d9Smrg      dispstr[exponent]='-';
4144d9b34d9Smrg    DrawDisplay();
4154d9b34d9Smrg    return;
4164d9b34d9Smrg  }
4174d9b34d9Smrg
4184d9b34d9Smrg  if (strcmp("0",dispstr)==0)
4194d9b34d9Smrg    return;			/* don't neg a zero */
4204d9b34d9Smrg  if (dispstr[0]=='-')	 	/* already neg-ed */
4214d9b34d9Smrg    strcpy(dispstr,dispstr+1);  /* move str left once */
4224d9b34d9Smrg  else {			/* not neg-ed.  add a '-' */
4234d9b34d9Smrg    char tmp[32];
4244d9b34d9Smrg    sprintf(tmp,"-%s",dispstr);
4254d9b34d9Smrg    strcpy(dispstr,tmp);
4264d9b34d9Smrg  }
4274d9b34d9Smrg  if (entered==2)
4284d9b34d9Smrg    dnum = -1.0 * dnum;
4294d9b34d9Smrg  DrawDisplay();
4304d9b34d9Smrg}
4314d9b34d9Smrg
4324d9b34d9Smrg/* Two operand functions for infix calc */
4334d9b34d9Smrgvoid
4344d9b34d9Smrgtwoop(int keynum)
4354d9b34d9Smrg{
4364d9b34d9Smrg  if (flagINV) {
4374d9b34d9Smrg    flagINV=0;
4384d9b34d9Smrg    DrawDisplay();
4394d9b34d9Smrg  }
4404d9b34d9Smrg
4414d9b34d9Smrg  if (!entered) {		/* something like "5+*" */
4424d9b34d9Smrg    if (!isopempty())
4434d9b34d9Smrg      (void) PopOp();			/* replace the prev op */
4444d9b34d9Smrg    PushOp(keynum);		/* with the new one */
4454d9b34d9Smrg    return;
4464d9b34d9Smrg  }
4474d9b34d9Smrg
4484d9b34d9Smrg  if (entered==1)
4494d9b34d9Smrg    parse_double(dispstr,"%lf",&dnum);
4504d9b34d9Smrg
4514d9b34d9Smrg  clrdisp=CLR=1;
4524d9b34d9Smrg  entered=Dpoint=exponent=0;
4534d9b34d9Smrg
4544d9b34d9Smrg  if (!isopempty()) {  /* there was a previous op */
4554d9b34d9Smrg    lastop=PopOp();   /* get it */
4564d9b34d9Smrg
4574d9b34d9Smrg    if (lastop==kLPAR) {  /* put it back */
4584d9b34d9Smrg      PushOp(kLPAR);
4594d9b34d9Smrg      PushOp(keynum);
4604d9b34d9Smrg      PushNum(dnum);
4614d9b34d9Smrg      return;
4624d9b34d9Smrg    }
4634d9b34d9Smrg
4644d9b34d9Smrg    /* now, if the current op (keynum) is of
4654d9b34d9Smrg       higher priority than the lastop, the current
4664d9b34d9Smrg       op and number are just pushed on top
4674d9b34d9Smrg       Priorities:  (Y^X) > *,/ > +,- */
4684d9b34d9Smrg
4694d9b34d9Smrg    if (priority(keynum) > priority(lastop)) {
4704d9b34d9Smrg      PushNum(dnum);
4714d9b34d9Smrg      PushOp(lastop);
4724d9b34d9Smrg      PushOp(keynum);
4734d9b34d9Smrg    } else {  /* execute lastop on lastnum and dnum, push
4744d9b34d9Smrg	       result and current op on stack */
4754d9b34d9Smrg      acc=PopNum();
4764d9b34d9Smrg      switch (lastop) { /* perform the operation */
4774d9b34d9Smrg      case kADD: acc += dnum;  break;
4784d9b34d9Smrg      case kSUB: acc -= dnum;  break;
4794d9b34d9Smrg      case kMUL: acc *= dnum;  break;
4804d9b34d9Smrg      case kDIV: acc /= dnum;  break;
4814d9b34d9Smrg      case kPOW: acc =  pow(acc,dnum);  break;
4824d9b34d9Smrg	}
4834d9b34d9Smrg      PushNum(acc);
4844d9b34d9Smrg      PushOp(keynum);
4854d9b34d9Smrg      sprintf(dispstr,"%.8g",acc);
4864d9b34d9Smrg      DrawDisplay();
4874d9b34d9Smrg      dnum=acc;
4884d9b34d9Smrg    }
4894d9b34d9Smrg  }
4904d9b34d9Smrg  else { /* op stack is empty, push op and num */
4914d9b34d9Smrg    PushOp(keynum);
4924d9b34d9Smrg    PushNum(dnum);
4934d9b34d9Smrg  }
4944d9b34d9Smrg}
4954d9b34d9Smrg
4964d9b34d9Smrg/* Two operand functions for rpn calc */
4974d9b34d9Smrgvoid
4984d9b34d9Smrgtwof(int keynum)
4994d9b34d9Smrg{
5004d9b34d9Smrg  if (flagINV) {
5014d9b34d9Smrg    flagINV=0;
5024d9b34d9Smrg    DrawDisplay();
5034d9b34d9Smrg  }
5044d9b34d9Smrg  if (!entered)
5054d9b34d9Smrg    return;
5064d9b34d9Smrg  if (entered==1)
5074d9b34d9Smrg    parse_double(dispstr, "%lf", &dnum);
5084d9b34d9Smrg  acc = PopNum();
5094d9b34d9Smrg  switch(keynum) {
5104d9b34d9Smrg  case kADD: acc += dnum;  break;
5114d9b34d9Smrg  case kSUB: acc -= dnum;  break;
5124d9b34d9Smrg  case kMUL: acc *= dnum;  break;
5134d9b34d9Smrg  case kDIV: acc /= dnum;  break;
5144d9b34d9Smrg  case kPOW: acc =  pow(acc,dnum);  break;
5154d9b34d9Smrg  case kXXY: PushNum(dnum);
5164d9b34d9Smrg  }
5174d9b34d9Smrg  sprintf(dispstr, "%.8g", acc);
5184d9b34d9Smrg  DrawDisplay();
5194d9b34d9Smrg  clrdisp++;
5204d9b34d9Smrg  Dpoint = exponent = 0;
5214d9b34d9Smrg  entered = 2;
5224d9b34d9Smrg  lift_enabled = 1;
5234d9b34d9Smrg  dnum = acc;
5244d9b34d9Smrg}
5254d9b34d9Smrg
5264d9b34d9Smrgvoid
5274d9b34d9Smrgentrf(void)
5284d9b34d9Smrg{
5294d9b34d9Smrg  flagINV=0;
5304d9b34d9Smrg  if (!entered)
5314d9b34d9Smrg    return;
5324d9b34d9Smrg
5334d9b34d9Smrg  clrdisp=CLR=1;
5344d9b34d9Smrg  Dpoint=exponent=0;
5354d9b34d9Smrg
5364d9b34d9Smrg  if (entered==1)
5374d9b34d9Smrg    parse_double(dispstr,"%lf",&dnum);
5384d9b34d9Smrg  entered=2;
5394d9b34d9Smrg  memop = kENTR;
5404d9b34d9Smrg  PushNum(dnum);
5414d9b34d9Smrg  lift_enabled = 0;
5424d9b34d9Smrg}
5434d9b34d9Smrg
5444d9b34d9Smrgvoid
5454d9b34d9Smrgequf(void)
5464d9b34d9Smrg{
5474d9b34d9Smrg  flagINV=0;
5484d9b34d9Smrg  if (!entered)
5494d9b34d9Smrg    return;
5504d9b34d9Smrg
5514d9b34d9Smrg  clrdisp=CLR=1;
5524d9b34d9Smrg  Dpoint=exponent=0;
5534d9b34d9Smrg
5544d9b34d9Smrg  if (entered==1)
5554d9b34d9Smrg    parse_double(dispstr,"%lf",&dnum);
5564d9b34d9Smrg  entered=2;
5574d9b34d9Smrg
5584d9b34d9Smrg  PushNum(dnum);
5594d9b34d9Smrg
5604d9b34d9Smrg  while (!isopempty()) {  /* do all pending ops */
5614d9b34d9Smrg    dnum=PopNum();
5624d9b34d9Smrg    acc=PopNum();
5634d9b34d9Smrg    lastop=PopOp();
5644d9b34d9Smrg    switch (lastop) {
5654d9b34d9Smrg    case kADD:  acc += dnum;
5664d9b34d9Smrg		break;
5674d9b34d9Smrg    case kSUB:  acc -= dnum;
5684d9b34d9Smrg		break;
5694d9b34d9Smrg    case kMUL:  acc *= dnum;
5704d9b34d9Smrg		break;
5714d9b34d9Smrg    case kDIV:  acc /= dnum;
5724d9b34d9Smrg		break;
5734d9b34d9Smrg    case kPOW:  acc = pow(acc,dnum);
5744d9b34d9Smrg		break;
5754d9b34d9Smrg    case kLPAR:	flagPAREN--;
5764d9b34d9Smrg		PushNum(acc);
5774d9b34d9Smrg		break;
5784d9b34d9Smrg    }
5794d9b34d9Smrg    dnum=acc;
5804d9b34d9Smrg    PushNum(dnum);
5814d9b34d9Smrg  }
5824d9b34d9Smrg
5834d9b34d9Smrg  sprintf(dispstr,"%.8g",dnum);
5844d9b34d9Smrg  DrawDisplay();
5854d9b34d9Smrg}
5864d9b34d9Smrg
5874d9b34d9Smrgvoid
5884d9b34d9Smrglparf(void)
5894d9b34d9Smrg{
5904d9b34d9Smrg  flagINV=0;
5914d9b34d9Smrg  PushOp(kLPAR);
5924d9b34d9Smrg  flagPAREN++;
5934d9b34d9Smrg  DrawDisplay();
5944d9b34d9Smrg}
5954d9b34d9Smrg
5964d9b34d9Smrgvoid
5974d9b34d9Smrgrollf(void)
5984d9b34d9Smrg{
5994d9b34d9Smrg  if (!entered)
6004d9b34d9Smrg    return;
6014d9b34d9Smrg  if (entered==1)
6024d9b34d9Smrg    parse_double(dispstr, "%lf", &dnum);
6034d9b34d9Smrg  entered = 2;
6044d9b34d9Smrg  lift_enabled = 1;
6054d9b34d9Smrg  RollNum(flagINV);
6064d9b34d9Smrg  flagINV=0;
6074d9b34d9Smrg  clrdisp++;
6084d9b34d9Smrg  sprintf(dispstr, "%.8g", dnum);
6094d9b34d9Smrg  DrawDisplay();
6104d9b34d9Smrg}
6114d9b34d9Smrg
6124d9b34d9Smrgvoid
6134d9b34d9Smrgrparf(void)
6144d9b34d9Smrg{
6154d9b34d9Smrg  flagINV=0;
6164d9b34d9Smrg  if (!entered)
6174d9b34d9Smrg    return;
6184d9b34d9Smrg
6194d9b34d9Smrg  if (!flagPAREN)
6204d9b34d9Smrg    return;
6214d9b34d9Smrg
6224d9b34d9Smrg  clrdisp++;
6234d9b34d9Smrg  Dpoint=exponent=0;
6244d9b34d9Smrg
6254d9b34d9Smrg  if (entered==1)
6264d9b34d9Smrg    parse_double(dispstr,"%lf",&dnum);
6274d9b34d9Smrg  entered=2;
6284d9b34d9Smrg
6294d9b34d9Smrg  PushNum(dnum);
6304d9b34d9Smrg  while (!isopempty() && (lastop=PopOp())!=kLPAR) {
6314d9b34d9Smrg    /* do all pending ops, back to left paren */
6324d9b34d9Smrg    dnum=PopNum();
6334d9b34d9Smrg    acc=PopNum();
6344d9b34d9Smrg    switch (lastop) {
6354d9b34d9Smrg    case kADD:  acc += dnum;
6364d9b34d9Smrg		break;
6374d9b34d9Smrg    case kSUB:  acc -= dnum;
6384d9b34d9Smrg		break;
6394d9b34d9Smrg    case kMUL:  acc *= dnum;
6404d9b34d9Smrg		break;
6414d9b34d9Smrg    case kDIV:  acc /= dnum;
6424d9b34d9Smrg		break;
6434d9b34d9Smrg    case kPOW:  acc = pow(acc,dnum);
6444d9b34d9Smrg		break;
6454d9b34d9Smrg    }
6464d9b34d9Smrg    dnum=acc;
6474d9b34d9Smrg    PushNum(dnum);
6484d9b34d9Smrg  }
6494d9b34d9Smrg  (void) PopNum();
6504d9b34d9Smrg  flagPAREN--;
6514d9b34d9Smrg  entered=2;
6524d9b34d9Smrg  sprintf(dispstr,"%.8g",dnum);
6534d9b34d9Smrg  DrawDisplay();
6544d9b34d9Smrg}
6554d9b34d9Smrg
6564d9b34d9Smrgvoid
6574d9b34d9Smrgdrgf(void)
6584d9b34d9Smrg{
6594d9b34d9Smrg  if (flagINV) {
6604d9b34d9Smrg    if (entered==1)
6614d9b34d9Smrg      parse_double(dispstr,"%lf",&dnum);
6624d9b34d9Smrg    switch (drgmode) {
6634d9b34d9Smrg    case DEG:  dnum=dnum*PI/180.0;    break;
6644d9b34d9Smrg    case RAD:  dnum=dnum*200.0/PI;    break;
6654d9b34d9Smrg    case GRAD: dnum=dnum*90.0/100.0;  break;
6664d9b34d9Smrg    }
6674d9b34d9Smrg    entered=2;
6684d9b34d9Smrg    clrdisp=1;
6694d9b34d9Smrg    flagINV=0;
6704d9b34d9Smrg    sprintf(dispstr,"%.8g",dnum);
6714d9b34d9Smrg  }
6724d9b34d9Smrg
6734d9b34d9Smrg  flagINV=0;
6744d9b34d9Smrg  drgmode = (drgmode + 1) % 3;
6754d9b34d9Smrg  switch (drgmode) {
6764d9b34d9Smrg  case DEG:  drg2rad=PI / 180.0;
6774d9b34d9Smrg	     rad2drg=180.0 / PI;
6784d9b34d9Smrg	     break;
6794d9b34d9Smrg  case RAD:  drg2rad=1.0;
6804d9b34d9Smrg	     rad2drg=1.0;
6814d9b34d9Smrg	     break;
6824d9b34d9Smrg  case GRAD: drg2rad=PI / 200.0;
6834d9b34d9Smrg	     rad2drg=200.0 / PI;
6844d9b34d9Smrg	     break;
6854d9b34d9Smrg  }
6864d9b34d9Smrg  DrawDisplay();
6874d9b34d9Smrg}
6884d9b34d9Smrg
6894d9b34d9Smrgvoid
6904d9b34d9Smrginvf(void)
6914d9b34d9Smrg{
6924d9b34d9Smrg  flagINV = ~flagINV;
6934d9b34d9Smrg  DrawDisplay();
6944d9b34d9Smrg}
6954d9b34d9Smrg
6964d9b34d9Smrgvoid
6974d9b34d9Smrgmemf(int keynum)
6984d9b34d9Smrg{
6994d9b34d9Smrg    memop = keynum;
7004d9b34d9Smrg    if (entered==1)
7014d9b34d9Smrg      parse_double(dispstr,"%lf",&dnum);
7024d9b34d9Smrg    entered = 2;
7034d9b34d9Smrg    clrdisp++;
7044d9b34d9Smrg    lift_enabled = 0;
7054d9b34d9Smrg}
7064d9b34d9Smrg
7074d9b34d9Smrgvoid
7084d9b34d9Smrgoneop(int keynum)
7094d9b34d9Smrg{
7104d9b34d9Smrg  int i,j;
7114d9b34d9Smrg  double dtmp;
7124d9b34d9Smrg
7134d9b34d9Smrg  if (entered==1)
7144d9b34d9Smrg    parse_double(dispstr,"%lf",&dnum);
7154d9b34d9Smrg  entered = 2;
7164d9b34d9Smrg
7174d9b34d9Smrg  switch (keynum) {  /* do the actual math fn. */
7184d9b34d9Smrg  case kE:     if (rpn && memop != kENTR) PushNum(dnum); dnum=E;  break;
7194d9b34d9Smrg  case kPI:    if (rpn && memop != kENTR) PushNum(dnum); dnum=PI;  break;
7204d9b34d9Smrg  case kRECIP: dnum=1.0/dnum;  break;
7214d9b34d9Smrg  case kSQR:   flagINV = !flagINV; /* fall through to */
7224d9b34d9Smrg  case kSQRT:  if (flagINV) dnum=dnum*dnum;
7234d9b34d9Smrg	       else dnum=sqrt(dnum);
7244d9b34d9Smrg	       break;
7254d9b34d9Smrg  case k10X:   flagINV = !flagINV; /* fall through to */
7264d9b34d9Smrg  case kLOG:   if (flagINV) dnum=pow(10.0,dnum);
7274d9b34d9Smrg  	       else dnum=log10(dnum);
7284d9b34d9Smrg	       break;
7294d9b34d9Smrg  case kEXP:   flagINV = !flagINV; /* fall through to */
7304d9b34d9Smrg  case kLN:    if (flagINV) dnum=exp(dnum);
7314d9b34d9Smrg	       else dnum=log(dnum);
7324d9b34d9Smrg	       break;
7334d9b34d9Smrg  case kSIN:   if (flagINV) dnum=asin(dnum)*rad2drg;
7344d9b34d9Smrg	       else dnum=sin(dnum*drg2rad);
7354d9b34d9Smrg	       break;
7364d9b34d9Smrg  case kCOS:   if (flagINV) dnum=acos(dnum)*rad2drg;
7374d9b34d9Smrg	       else dnum=cos(dnum*drg2rad);
7384d9b34d9Smrg	       break;
7394d9b34d9Smrg  case kTAN:   if (flagINV) dnum=atan(dnum)*rad2drg;
7404d9b34d9Smrg	       else dnum=tan(dnum*drg2rad);
7414d9b34d9Smrg	       break;
7424d9b34d9Smrg  case kSTO:   mem[0]=dnum;  flagM=!(mem[0]==0.0);  break;
7434d9b34d9Smrg  case kRCL:   if (rpn && lift_enabled) PushNum(dnum);
7444d9b34d9Smrg               dnum=mem[0];  flagM=!(mem[0]==0.0);  break;
7454d9b34d9Smrg  case kSUM:   mem[0]+=dnum; flagM=!(mem[0]==0.0);  break;
7464d9b34d9Smrg  case kEXC:   dtmp=dnum; dnum=mem[0];  mem[0]=dtmp;
7474d9b34d9Smrg	       flagM=!(mem[0]==0.0);  break;
7484d9b34d9Smrg  case kFACT:  if (floor(dnum)!=dnum || dnum<0.0 || dnum>500.0) {
7494d9b34d9Smrg		 strcpy(dispstr,"error");
7504d9b34d9Smrg		 entered=3;
7514d9b34d9Smrg		 break;
7524d9b34d9Smrg	       }
7538512f934Smrg	       dtmp = floor(dnum); i = dtmp;
7544d9b34d9Smrg	       for (j=1,dnum=1.0; j<=i; j++)
7554d9b34d9Smrg		 dnum*=(float) j;
7564d9b34d9Smrg	       break;
7574d9b34d9Smrg  }
7584d9b34d9Smrg
7594d9b34d9Smrg  if (entered==3) {  /* error */
7604d9b34d9Smrg    DrawDisplay();
7614d9b34d9Smrg    return;
7624d9b34d9Smrg  }
7634d9b34d9Smrg
7644d9b34d9Smrg  memop = keynum;
7654d9b34d9Smrg  entered=2;
7664d9b34d9Smrg  clrdisp=1;
7674d9b34d9Smrg  flagINV=0;
7684d9b34d9Smrg  lift_enabled = 1;
7694d9b34d9Smrg  sprintf(dispstr,"%.8g",dnum);
7704d9b34d9Smrg  DrawDisplay();
7714d9b34d9Smrg}
7724d9b34d9Smrg
7734d9b34d9Smrgvoid
7744d9b34d9Smrgofff(void)
7754d9b34d9Smrg{
7764d9b34d9Smrg  /* full reset */
7774d9b34d9Smrg  int i;
7784d9b34d9Smrg  ResetCalc();
7794d9b34d9Smrg  entered=clrdisp=1;
7804d9b34d9Smrg  lift_enabled = 0;
7814d9b34d9Smrg  dnum=mem[0]=0.0;
7824d9b34d9Smrg  if (rpn)
7834d9b34d9Smrg      for (i=1; i < XCALC_MEMORY; i++)
7844d9b34d9Smrg	  mem[i]=0.0;
7854d9b34d9Smrg  exponent=Dpoint=0;
7864d9b34d9Smrg  DrawDisplay();
7874d9b34d9Smrg}
7884d9b34d9Smrg
7894d9b34d9Smrg
7904d9b34d9Smrg#define STACKMAX 32
7914d9b34d9Smrgstatic int opstack[STACKMAX];
7924d9b34d9Smrgstatic int opsp;
7934d9b34d9Smrgstatic double numstack[STACKMAX];
7944d9b34d9Smrgstatic int numsp;
7954d9b34d9Smrg
7964d9b34d9Smrg
7974d9b34d9Smrg/*******/
7984d9b34d9Smrgstatic void
7998512f934SmrgPushOp(int op)
8004d9b34d9Smrg/*******/
8014d9b34d9Smrg{
8024d9b34d9Smrg  if (opsp==STACKMAX) {strcpy(dispstr,"stack error");  entered=3;}
8034d9b34d9Smrg  else opstack[opsp++]=op;
8044d9b34d9Smrg}
8054d9b34d9Smrg
8064d9b34d9Smrg/*******/
8074d9b34d9Smrgstatic int
8084d9b34d9SmrgPopOp(void)
8094d9b34d9Smrg/*******/
8104d9b34d9Smrg{
8114d9b34d9Smrg  if (opsp==0) {
8124d9b34d9Smrg      strcpy(dispstr,"stack error");
8134d9b34d9Smrg      entered=3;
8144d9b34d9Smrg      return(kNOP);
8154d9b34d9Smrg  } else
8164d9b34d9Smrg    return(opstack[--opsp]);
8174d9b34d9Smrg}
8184d9b34d9Smrg
8194d9b34d9Smrg/*******/
8204d9b34d9Smrgstatic int
8214d9b34d9Smrgisopempty(void)
8224d9b34d9Smrg/*******/
8234d9b34d9Smrg{
8244d9b34d9Smrg  return( opsp ? 0 : 1 );
8254d9b34d9Smrg}
8264d9b34d9Smrg
8274d9b34d9Smrg#ifdef DEBUG
8284d9b34d9Smrgstatic void
8298512f934Smrgshowstack(char *string)
8304d9b34d9Smrg{
8314d9b34d9Smrg    fprintf(stderr, "%s: %lf %lf %lf\n", string, numstack[0], numstack[1],
8324d9b34d9Smrg	    numstack[2]);
8334d9b34d9Smrg}
8344d9b34d9Smrg#endif
8354d9b34d9Smrg
8364d9b34d9Smrg/*******/
8374d9b34d9Smrgstatic void
8388512f934SmrgPushNum(double num)
8394d9b34d9Smrg/*******/
8404d9b34d9Smrg{
8414d9b34d9Smrg  if (rpn) {
8424d9b34d9Smrg      numstack[2] = numstack[1];
8434d9b34d9Smrg      numstack[1] = numstack[0];
8444d9b34d9Smrg      numstack[0] = num;
8454d9b34d9Smrg      return;
8464d9b34d9Smrg  }
8474d9b34d9Smrg  if (numsp==STACKMAX) {
8484d9b34d9Smrg      strcpy(dispstr,"stack error");
8494d9b34d9Smrg      entered=3;
8504d9b34d9Smrg  } else
8514d9b34d9Smrg    numstack[numsp++]=num;
8524d9b34d9Smrg}
8534d9b34d9Smrg
8544d9b34d9Smrg/*******/
8554d9b34d9Smrgstatic double
8564d9b34d9SmrgPopNum(void)
8574d9b34d9Smrg/*******/
8584d9b34d9Smrg{
8594d9b34d9Smrg    if (rpn) {
8604d9b34d9Smrg	double tmp = numstack[0];
8614d9b34d9Smrg	numstack[0] = numstack[1];
8624d9b34d9Smrg	numstack[1] = numstack[2];
8634d9b34d9Smrg	return(tmp);
8644d9b34d9Smrg    }
8654d9b34d9Smrg    if (numsp==0) {
8664d9b34d9Smrg	strcpy(dispstr,"stack error");
8674d9b34d9Smrg	entered=3;
8684d9b34d9Smrg	return 0.0;
8694d9b34d9Smrg    } else
8704d9b34d9Smrg      return(numstack[--numsp]);
8714d9b34d9Smrg}
8724d9b34d9Smrg
8734d9b34d9Smrg/*******/
8744d9b34d9Smrgstatic void
8754d9b34d9SmrgRollNum(int dir)
8764d9b34d9Smrg/*******/
8774d9b34d9Smrg{
8784d9b34d9Smrg    double tmp;
8794d9b34d9Smrg
8804d9b34d9Smrg    if (dir) {				/* roll up */
8814d9b34d9Smrg	tmp         = dnum;
8824d9b34d9Smrg	dnum        = numstack[2];
8834d9b34d9Smrg	numstack[2] = numstack[1];
8844d9b34d9Smrg	numstack[1] = numstack[0];
8854d9b34d9Smrg	numstack[0] = tmp;
8864d9b34d9Smrg    } else {				/* roll down */
8874d9b34d9Smrg	tmp         = dnum;
8884d9b34d9Smrg	dnum        = numstack[0];
8894d9b34d9Smrg	numstack[0] = numstack[1];
8904d9b34d9Smrg	numstack[1] = numstack[2];
8914d9b34d9Smrg	numstack[2] = tmp;
8924d9b34d9Smrg    }
8934d9b34d9Smrg}
8944d9b34d9Smrg
8954d9b34d9Smrg
8964d9b34d9Smrg/*******/
8974d9b34d9Smrgstatic void
8984d9b34d9SmrgClearStacks(void)
8994d9b34d9Smrg/*******/
9004d9b34d9Smrg{
9014d9b34d9Smrg    if (rpn)
9024d9b34d9Smrg      numstack[0] = numstack[1] = numstack[2] = 0.;
9034d9b34d9Smrg    opsp=numsp=0;
9044d9b34d9Smrg}
9054d9b34d9Smrg
9064d9b34d9Smrg
9074d9b34d9Smrg/*******/
9084d9b34d9Smrgstatic int
9098512f934Smrgpriority(int op)
9104d9b34d9Smrg/*******/
9114d9b34d9Smrg{
9124d9b34d9Smrg    switch (op) {
9134d9b34d9Smrg        case kPOW: return(2);
9144d9b34d9Smrg        case kMUL:
9154d9b34d9Smrg        case kDIV: return(1);
9164d9b34d9Smrg        case kADD:
9174d9b34d9Smrg        case kSUB: return(0);
9184d9b34d9Smrg        }
9194d9b34d9Smrg    return 0;
9204d9b34d9Smrg}
9214d9b34d9Smrg
9224d9b34d9Smrg
9234d9b34d9Smrg/********/
9244d9b34d9Smrgvoid
9254d9b34d9SmrgResetCalc(void)
9264d9b34d9Smrg/********/
9274d9b34d9Smrg{
9284d9b34d9Smrg    flagM=flagINV=flagPAREN=0;  drgmode=DEG;
9294d9b34d9Smrg    setflag(XCalc_MEMORY, False);
9304d9b34d9Smrg    setflag(XCalc_INVERSE, False);
9314d9b34d9Smrg    setflag(XCalc_PAREN, False);
9324d9b34d9Smrg    setflag(XCalc_RADIAN, False);
9334d9b34d9Smrg    setflag(XCalc_GRADAM, False);
9344d9b34d9Smrg    setflag(XCalc_DEGREE, True);
9354d9b34d9Smrg    strcpy(dispstr,"0");
9364d9b34d9Smrg    draw(dispstr);
9374d9b34d9Smrg    ClearStacks();
9384d9b34d9Smrg    drg2rad=PI/180.0;
9394d9b34d9Smrg    rad2drg=180.0/PI;
9404d9b34d9Smrg}
941