home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* Copyright 1988 by Chuck Musciano and Harris Corporation */
- /* */
- /* Permission to use, copy, modify, and distribute this software */
- /* and its documentation for any purpose and without fee is */
- /* hereby granted, provided that the above copyright notice */
- /* appear in all copies and that both that copyright notice and */
- /* this permission notice appear in supporting documentation, and */
- /* that the name of Chuck Musciano and Harris Corporation not be */
- /* used in advertising or publicity pertaining to distribution */
- /* of the software without specific, written prior permission. */
- /* Chuck Musciano and Harris Corporation make no representations */
- /* about the suitability of this software for any purpose. It is */
- /* provided "as is" without express or implied warranty. */
- /************************************************************************/
-
- /************************************************************************/
- /* */
- /* Module: ops.c */
- /* */
- /* Function: Perform actual calculation */
- /* */
- /* Public Names: do_unary handle unary operators */
- /* do_binary handle binary operators */
- /* op_str return a operator string */
- /* */
- /* Change History: 17 Nov 86 Creation */
- /* */
- /************************************************************************/
-
- #include <math.h>
-
- #include "manifest.h"
- #include "globals.h"
- #include "keys.h"
-
- #define low_order(b, x) ((((unsigned) 0xffffffff) >> (32 - (b))) & (x))
-
- PRIVATE pop_op()
-
- { int i, temp;
-
- if (curr_mode != SCIENTIFIC && o_stack[o_top - 1]) {
- v_stack[v_top] = (double) low_order(curr_width[index_of(curr_base)], (unsigned int) v_stack[v_top]);
- v_stack[v_top - 1] = (double) low_order(curr_width[index_of(curr_base)], (unsigned int) v_stack[v_top - 1]);
- }
- switch (o_stack[--o_top]) {
- case ADD_OP : v_stack[v_top - 1] += v_stack[v_top];
- break;
- case AND_OP : temp = ((unsigned int) v_stack[v_top - 1]) & ((unsigned int) v_stack[v_top]);
- v_stack[v_top - 1] = (double) temp;
- break;
- case DIV_OP : v_stack[v_top - 1] /= v_stack[v_top];
- break;
- case LPAREN_OP : return;
- break;
- case LSL_OP : temp = ((unsigned int) v_stack[v_top - 1]) << ((unsigned int) v_stack[v_top]);
- v_stack[v_top - 1] = (double) temp;
- break;
- case MUL_OP : v_stack[v_top - 1] *= v_stack[v_top];
- break;
- case OR_OP : temp = ((unsigned int) v_stack[v_top - 1]) | ((unsigned int) v_stack[v_top]);
- v_stack[v_top - 1] = (double) temp;
- break;
- case ROL_OP : for (i = (unsigned int) v_stack[v_top], temp = (unsigned int) v_stack[v_top - 1]; i; i--)
- temp = (temp << 1) + ((((unsigned) temp) >> (curr_width[index_of(curr_base)] - 1)) & 1);
- v_stack[v_top - 1] = (double) low_order(curr_width[index_of(curr_base)], temp);
- break;
- case ROOT_OP : v_stack[v_top - 1] = pow(v_stack[v_top - 1], 1.0 / v_stack[v_top]);
- break;
- case ROR_OP : for (i = (unsigned int) v_stack[v_top], temp = (unsigned int) v_stack[v_top - 1]; i; i--)
- temp = (((unsigned) temp) >> 1) + ((temp & 1) << (curr_width[index_of(curr_base)] - 1));
- v_stack[v_top - 1] = (double) low_order(curr_width[index_of(curr_base)], temp);
- break;
- case RSA_OP : temp = ((unsigned int) v_stack[v_top - 1]) >> ((unsigned int) v_stack[v_top]);
- v_stack[v_top - 1] = (double) temp;
- break;
- case RSL_OP : temp = ((unsigned int) ((unsigned int) v_stack[v_top - 1])) >> ((unsigned int) v_stack[v_top]);
- v_stack[v_top - 1] = (double) temp;
- break;
- case SUB_OP : v_stack[v_top - 1] -= v_stack[v_top];
- break;
- case XOR_OP : temp = ((unsigned int) v_stack[v_top - 1]) ^ ((unsigned int) v_stack[v_top]);
- v_stack[v_top - 1] = (double) temp;
- break;
- case Y2X_OP : v_stack[v_top - 1] = pow(v_stack[v_top - 1], v_stack[v_top]);
- break;
- }
- v_top--;
- }
-
- PRIVATE reduce_stack(pr)
-
- int pr;
-
- {
- while (o_top > 0 && pr <= prec(o_stack[o_top - 1]))
- pop_op();
- }
-
- PRIVATE double to_rads(val)
-
- double val;
-
- {
- if (trig_mode == DEG)
- return(val / 180.0 * PI);
- else if (trig_mode == GRAD)
- return(val / 200.0 * PI);
- else
- return(val);
- }
-
- PRIVATE double from_rads(val)
-
- double val;
-
- {
- if (trig_mode == DEG)
- return(val / PI * 180.0);
- else if (trig_mode == GRAD)
- return(val / PI * 200.0);
- else
- return(val);
- }
-
- PUBLIC char *op_str(op)
-
- int op;
-
- {
- switch (op) {
- case ADD_OP : return("+");
- case AND_OP : return("&");
- case DIV_OP : return("\205");
- case LPAREN_OP : return("(");
- case LSL_OP : return("\200");
- case MUL_OP : return("X");
- case OR_OP : return("|");
- case ROL_OP : return("\202");
- case ROOT_OP : return("\207\210");
- case ROR_OP : return("\203");
- case RSA_OP : return("\204");
- case RSL_OP : return("\201");
- case SUB_OP : return("-");
- case XOR_OP : return("^");
- case Y2X_OP : return("\206");
- default : return("");
- }
- }
-
- PUBLIC do_unary(op)
-
- int op;
-
- { int temp;
-
- convert_display();
- switch (op) {
- case CLEAR_OP : v_stack[v_top = 0] = 0.0;
- o_top = 0;
- break;
- case ERASE_OP : clear_entry();
- do_digit(DIGIT_0);
- break;
- case EQUAL_OP : reduce_stack(-1);
- break;
- case LPAREN_OP : o_stack[o_top++] = LPAREN_OP;
- break;
- case RPAREN_OP : reduce_stack(prec(op));
- o_top--;
- break;
- case INVEE_OP : ee_mode = FALSE;
- break;
- case COS_OP : v_stack[v_top] = cos(to_rads(v_stack[v_top]));
- break;
- case EXP_OP : v_stack[v_top] = exp(v_stack[v_top]);
- break;
- case E_OP : v_stack[v_top] = E;
- break;
- case FACT_OP : temp = (int) v_stack[v_top];
- if (temp < 0 || temp > 170)
- v_stack[v_top] /= 0.0;
- else if (temp == 0)
- v_stack[v_top] = 1.0;
- else
- for (v_stack[v_top] = 1.0; temp; temp--)
- v_stack[v_top] *= (double) temp;
- break;
- case ICOS_OP : v_stack[v_top] = from_rads(acos(v_stack[v_top]));
- break;
- case INT_OP : v_stack[v_top] = (double) ((int) v_stack[v_top]);
- break;
- case ISIN_OP : v_stack[v_top] = from_rads(asin(v_stack[v_top]));
- break;
- case ITAN_OP : v_stack[v_top] = from_rads(atan(v_stack[v_top]));
- break;
- case LN_OP : v_stack[v_top] = log(v_stack[v_top]);
- break;
- case LOG_OP : v_stack[v_top] = log10(v_stack[v_top]);
- break;
- case NOT_OP : v_stack[v_top] = (double) low_order(curr_width[index_of(curr_base)], (~ (unsigned int) v_stack[v_top]));
- break;
- case OVER_OP : v_stack[v_top] = 1.0 / v_stack[v_top];
- break;
- case PI_OP : v_stack[v_top] = PI;
- break;
- case POW_OP : v_stack[v_top] = pow(10.0, v_stack[v_top]);
- break;
- case SIN_OP : v_stack[v_top] = sin(to_rads(v_stack[v_top]));
- break;
- case SQRT_OP : v_stack[v_top] = sqrt(v_stack[v_top]);
- break;
- case SQR_OP : v_stack[v_top] *= v_stack[v_top];
- break;
- case TAN_OP : v_stack[v_top] = tan(to_rads(v_stack[v_top]));
- break;
- case TRUNC_OP : if (curr_width[0] != -1) {
- v_stack[v_top] *= pow(10.0, (double) curr_width[0]);
- v_stack[v_top] = (double) ((int) v_stack[v_top]);
- v_stack[v_top] /= pow(10.0, (double) curr_width[0]);
- }
- break;
- }
- update_display();
- }
-
- PUBLIC do_binary(op)
-
- int op;
-
- {
- convert_display();
- reduce_stack(prec(op));
- o_stack[o_top++] = op;
- v_top += 1;
- v_stack[v_top] = v_stack[v_top - 1];
- update_display();
- }
-