home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume1 / calctool / part02 / ops.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-29  |  7.9 KB  |  240 lines

  1. /************************************************************************/
  2. /*    Copyright 1988 by Chuck Musciano and Harris Corporation        */
  3. /*                                    */
  4. /*    Permission to use, copy, modify, and distribute this software    */
  5. /*    and its documentation for any purpose and without fee is    */
  6. /*    hereby granted, provided that the above copyright notice    */
  7. /*    appear in all copies and that both that copyright notice and    */
  8. /*    this permission notice appear in supporting documentation, and    */
  9. /*    that the name of Chuck Musciano and Harris Corporation not be    */
  10. /*    used in advertising or publicity pertaining to distribution    */
  11. /*    of the software without specific, written prior permission.    */
  12. /*    Chuck Musciano and Harris Corporation make no representations    */
  13. /*    about the suitability of this software for any purpose.  It is    */
  14. /*    provided "as is" without express or implied warranty.        */
  15. /************************************************************************/
  16.  
  17. /************************************************************************/
  18. /*                                    */
  19. /*    Module:        ops.c                        */
  20. /*                                    */
  21. /*    Function:    Perform actual calculation            */
  22. /*                                    */
  23. /*    Public Names:    do_unary    handle unary operators        */
  24. /*            do_binary    handle binary operators        */
  25. /*            op_str        return a operator string    */
  26. /*                                    */
  27. /*    Change History:    17 Nov 86    Creation            */
  28. /*                                    */
  29. /************************************************************************/
  30.  
  31. #include    <math.h>
  32.  
  33. #include    "manifest.h"
  34. #include    "globals.h"
  35. #include    "keys.h"
  36.  
  37. #define        low_order(b, x)        ((((unsigned) 0xffffffff) >> (32 - (b))) & (x))
  38.  
  39. PRIVATE    pop_op()
  40.  
  41. {    int    i, temp;
  42.  
  43.     if (curr_mode != SCIENTIFIC && o_stack[o_top - 1]) {
  44.        v_stack[v_top] = (double) low_order(curr_width[index_of(curr_base)], (unsigned int) v_stack[v_top]);
  45.        v_stack[v_top - 1] = (double) low_order(curr_width[index_of(curr_base)], (unsigned int) v_stack[v_top - 1]);
  46.        }
  47.     switch (o_stack[--o_top]) {
  48.        case ADD_OP    : v_stack[v_top - 1] += v_stack[v_top];
  49.                        break;
  50.        case AND_OP    : temp = ((unsigned int) v_stack[v_top - 1]) & ((unsigned int) v_stack[v_top]);
  51.                        v_stack[v_top - 1] = (double) temp;
  52.                        break;
  53.        case DIV_OP    : v_stack[v_top - 1] /= v_stack[v_top];
  54.                        break;
  55.        case LPAREN_OP : return;
  56.                    break;
  57.        case LSL_OP    : temp = ((unsigned int) v_stack[v_top - 1]) << ((unsigned int) v_stack[v_top]);
  58.                        v_stack[v_top - 1] = (double) temp;
  59.                        break;
  60.        case MUL_OP    : v_stack[v_top - 1] *= v_stack[v_top];
  61.                        break;
  62.        case OR_OP     : temp = ((unsigned int) v_stack[v_top - 1]) | ((unsigned int) v_stack[v_top]);
  63.                        v_stack[v_top - 1] = (double) temp;
  64.                        break;
  65.        case ROL_OP    : for (i = (unsigned int) v_stack[v_top], temp = (unsigned int) v_stack[v_top - 1]; i; i--)
  66.                       temp = (temp << 1) + ((((unsigned) temp) >> (curr_width[index_of(curr_base)] - 1)) & 1);
  67.                    v_stack[v_top - 1] = (double) low_order(curr_width[index_of(curr_base)], temp);
  68.                        break;
  69.        case ROOT_OP   : v_stack[v_top - 1] = pow(v_stack[v_top - 1], 1.0 / v_stack[v_top]);
  70.                        break;
  71.        case ROR_OP    : for (i = (unsigned int) v_stack[v_top], temp = (unsigned int) v_stack[v_top - 1]; i; i--)
  72.                       temp = (((unsigned) temp) >> 1) + ((temp & 1) << (curr_width[index_of(curr_base)] - 1));
  73.                    v_stack[v_top - 1] = (double) low_order(curr_width[index_of(curr_base)], temp);
  74.                        break;
  75.        case RSA_OP    : temp = ((unsigned int) v_stack[v_top - 1]) >> ((unsigned int) v_stack[v_top]);
  76.                        v_stack[v_top - 1] = (double) temp;
  77.                        break;
  78.        case RSL_OP    : temp = ((unsigned int) ((unsigned int) v_stack[v_top - 1])) >> ((unsigned int) v_stack[v_top]);
  79.                        v_stack[v_top - 1] = (double) temp;
  80.                        break;
  81.        case SUB_OP    : v_stack[v_top - 1] -= v_stack[v_top];
  82.                        break;
  83.        case XOR_OP    : temp = ((unsigned int) v_stack[v_top - 1]) ^ ((unsigned int) v_stack[v_top]);
  84.                        v_stack[v_top - 1] = (double) temp;
  85.                        break;
  86.        case Y2X_OP    : v_stack[v_top - 1] = pow(v_stack[v_top - 1], v_stack[v_top]);
  87.                        break;
  88.        }
  89.     v_top--;
  90. }
  91.  
  92. PRIVATE    reduce_stack(pr)
  93.  
  94. int    pr;
  95.  
  96. {
  97.     while (o_top > 0 && pr <= prec(o_stack[o_top - 1]))
  98.        pop_op();
  99. }
  100.  
  101. PRIVATE    double    to_rads(val)
  102.  
  103. double    val;
  104.  
  105. {
  106.     if (trig_mode == DEG)
  107.        return(val / 180.0 * PI);
  108.     else if (trig_mode == GRAD)
  109.        return(val / 200.0 * PI);
  110.     else
  111.        return(val);
  112. }
  113.  
  114. PRIVATE    double    from_rads(val)
  115.  
  116. double    val;
  117.  
  118. {
  119.     if (trig_mode == DEG)
  120.        return(val / PI * 180.0);
  121.     else if (trig_mode == GRAD)
  122.        return(val / PI * 200.0);
  123.     else
  124.        return(val);
  125. }
  126.  
  127. PUBLIC    char    *op_str(op)
  128.  
  129. int    op;
  130.  
  131. {
  132.     switch (op) {
  133.        case ADD_OP    : return("+");
  134.        case AND_OP    : return("&");
  135.        case DIV_OP    : return("\205");
  136.        case LPAREN_OP : return("(");
  137.        case LSL_OP    : return("\200");
  138.        case MUL_OP    : return("X");
  139.        case OR_OP     : return("|");
  140.        case ROL_OP    : return("\202");
  141.        case ROOT_OP   : return("\207\210");
  142.        case ROR_OP    : return("\203");
  143.        case RSA_OP    : return("\204");
  144.        case RSL_OP    : return("\201");
  145.        case SUB_OP    : return("-");
  146.        case XOR_OP    : return("^");
  147.        case Y2X_OP    : return("\206");
  148.        default      : return("");
  149.        }
  150. }
  151.  
  152. PUBLIC    do_unary(op)
  153.  
  154. int    op;
  155.  
  156. {    int    temp;
  157.  
  158.     convert_display();
  159.     switch (op) {
  160.        case CLEAR_OP  : v_stack[v_top = 0] = 0.0;
  161.                    o_top = 0;
  162.                    break;
  163.        case ERASE_OP  : clear_entry();
  164.                    do_digit(DIGIT_0);
  165.                    break;
  166.        case EQUAL_OP  : reduce_stack(-1);
  167.                    break;
  168.        case LPAREN_OP : o_stack[o_top++] = LPAREN_OP;
  169.                    break;
  170.        case RPAREN_OP : reduce_stack(prec(op));
  171.                    o_top--;
  172.                    break;
  173.        case INVEE_OP  : ee_mode = FALSE;
  174.                    break;
  175.        case COS_OP    : v_stack[v_top] = cos(to_rads(v_stack[v_top]));
  176.                       break;
  177.        case EXP_OP    : v_stack[v_top] = exp(v_stack[v_top]);
  178.                       break;
  179.        case E_OP      : v_stack[v_top] = E;
  180.                       break;
  181.        case FACT_OP   : temp = (int) v_stack[v_top];
  182.                       if (temp < 0 || temp > 170)
  183.                          v_stack[v_top] /= 0.0;
  184.                       else if (temp == 0)
  185.                          v_stack[v_top] = 1.0;
  186.                       else
  187.                          for (v_stack[v_top] = 1.0; temp; temp--)
  188.                             v_stack[v_top] *= (double) temp;
  189.                       break;
  190.        case ICOS_OP   : v_stack[v_top] = from_rads(acos(v_stack[v_top]));
  191.                       break;
  192.        case INT_OP    : v_stack[v_top] = (double) ((int) v_stack[v_top]);
  193.                       break;
  194.        case ISIN_OP   : v_stack[v_top] = from_rads(asin(v_stack[v_top]));
  195.                       break;
  196.        case ITAN_OP   : v_stack[v_top] = from_rads(atan(v_stack[v_top]));
  197.                       break;
  198.        case LN_OP     : v_stack[v_top] = log(v_stack[v_top]);
  199.                       break;
  200.        case LOG_OP    : v_stack[v_top] = log10(v_stack[v_top]);
  201.                       break;
  202.        case NOT_OP    : v_stack[v_top] = (double) low_order(curr_width[index_of(curr_base)], (~ (unsigned int) v_stack[v_top]));
  203.                       break;
  204.        case OVER_OP   : v_stack[v_top] = 1.0 / v_stack[v_top];
  205.                       break;
  206.        case PI_OP     : v_stack[v_top] = PI;
  207.                       break;
  208.        case POW_OP    : v_stack[v_top] = pow(10.0, v_stack[v_top]);
  209.                       break;
  210.        case SIN_OP    : v_stack[v_top] = sin(to_rads(v_stack[v_top]));
  211.                       break;
  212.        case SQRT_OP   : v_stack[v_top] = sqrt(v_stack[v_top]);
  213.                       break;
  214.        case SQR_OP    : v_stack[v_top] *= v_stack[v_top];
  215.                       break;
  216.        case TAN_OP    : v_stack[v_top] = tan(to_rads(v_stack[v_top]));
  217.                       break;
  218.        case TRUNC_OP  : if (curr_width[0] != -1) {
  219.                          v_stack[v_top] *= pow(10.0, (double) curr_width[0]);
  220.                          v_stack[v_top] = (double) ((int) v_stack[v_top]);
  221.                          v_stack[v_top] /= pow(10.0, (double) curr_width[0]);
  222.                          }
  223.                        break;
  224.           }
  225.     update_display();
  226. }
  227.  
  228. PUBLIC    do_binary(op)
  229.  
  230. int    op;
  231.  
  232. {
  233.     convert_display();
  234.     reduce_stack(prec(op));
  235.     o_stack[o_top++] = op;
  236.     v_top += 1;
  237.     v_stack[v_top] = v_stack[v_top - 1];
  238.     update_display();
  239. }
  240.