Annotation of pmsdk/samples/calc/calcmath.c, revision 1.1.1.1

1.1       root        1: /****************************** Module Header ******************************\
                      2: * Module Name: calcmath.c - Calc application
                      3: *
                      4: * OS/2 Presentation Manager version of Calc, ported from Windows version
                      5: *
                      6: * Created by Microsoft Corporation, 1987
                      7: *
                      8: \***************************************************************************/
                      9: 
                     10: #define INCL_PM
                     11: #include <os2.h>
                     12: #include <string.h>
                     13: #include <stdio.h>
                     14: #include <stdlib.h>
                     15: #include <math.h>
                     16: 
                     17: BOOL   fReadNumber;
                     18: extern BOOL fValueInMemory;
                     19: extern char currkey;
                     20: extern char szreg1[20], szreg2[20], szmem[20];
                     21: char   PendingOperation;
                     22: extern HWND hwndCalc;
                     23: BOOL   fFirstOperand, fError;
                     24: extern char lastkey;
                     25: char temp[30];
                     26: char szresult[20];
                     27: extern char szregx[];
                     28: SEL sel;
                     29: 
                     30: #define tolower(x)   (((x) >= 'A') && ((x)<='Z')) ? (x) - 'A' + 'a' : (x)
                     31: #define MAXINT (double)999999999
                     32: #define MININT (double)-999999999
                     33: #define ABS(x)         (((x) >= (double)0) ? (x) : (-(x)))
                     34: 
                     35: extern VOID FarStrcpy( PSZ, PSZ);
                     36: extern VOID UpdateDisplay( VOID);
                     37: extern BOOL InterpretChar( CHAR);
                     38: 
                     39: VOID AppendNumber( BYTE);
                     40: VOID BinaryOperator( CHAR);
                     41: VOID Clear( VOID);
                     42: VOID DataXCopy( VOID);
                     43: VOID DataXPaste( VOID);
                     44: VOID Equilibrate( VOID);
                     45: VOID Evaluate( BYTE);
                     46: NPCH ftoa( double);
                     47: VOID InitCalc( VOID);
                     48: VOID MClear( VOID);
                     49: VOID MMinus( VOID);
                     50: VOID MPlus( VOID);
                     51: VOID Negate( VOID);
                     52: VOID Number( CHAR);
                     53: VOID Percent( VOID);
                     54: VOID reverse( NPCH);
                     55: VOID Simplify( VOID);
                     56: VOID SquareRoot( VOID);
                     57: 
                     58: 
                     59: VOID reverse(s)
                     60: NPCH s;
                     61: {
                     62:     CHAR c;
                     63:     register int i, j;
                     64: 
                     65:     for (i = 0, j = strlen(s) - 1; i<j; i++, j-- ) {
                     66:         c = s[i];
                     67:         s[i] = s[j];
                     68:         s[j] = c;
                     69:     }
                     70: }
                     71: 
                     72: NPCH ftoa(num)
                     73: double num;
                     74: {
                     75:     sprintf( szresult, "%.8f", num );
                     76:     return (szresult);
                     77: }
                     78: 
                     79: 
                     80: VOID Negate()
                     81: {
                     82:     char sztemp[ 20 ];
                     83: 
                     84:     if (szreg1[0] ==  '-') {
                     85:              /* get rid of minus sign */
                     86:         strcpy(szreg1, (&szreg1[1]));
                     87:         }
                     88:          /* can negate anything but zero */
                     89:     else if (szreg1[0] != '0' || (strlen(szreg1) > 2)) {
                     90:         sztemp[0] = '-';
                     91:         strcpy(&sztemp[1], szreg1);
                     92:         strcpy(szreg1, sztemp);
                     93:        }
                     94: }
                     95: 
                     96: VOID Number( n )
                     97: CHAR n;
                     98: {
                     99:     register int len, size;
                    100: 
                    101:     size = 9;
                    102:     if (szreg1[0] == '-') size++;
                    103:     if (strchr(szreg1, '.')) size++;
                    104:     len  = strlen(szreg1 );
                    105:     if (len == size) return;
                    106:     if (len == 1 && szreg1[0] == '0') len--;
                    107:     szreg1[ len ] = n;
                    108:     szreg1[min(len + 1, 11)] = 0;
                    109: }
                    110: 
                    111: VOID AppendNumber ( num )
                    112: BYTE num;
                    113: {
                    114:     if (num == '.') {    /*  if no decimal, add one at end */
                    115:         if (!strchr(szreg1, '.'))   
                    116:             strcat(szreg1, ".");
                    117:         }
                    118:     else if ( num == 0xb1 ) {
                    119:         Negate();
                    120:         }
                    121:     else {
                    122:         Number(num);
                    123:         }
                    124: }
                    125: 
                    126: VOID Equilibrate()
                    127: {
                    128:     double result; 
                    129:     double x1, x2;
                    130: 
                    131:     if (lastkey == '=') return;
                    132:     result = (double)atof(szreg1);
                    133:     x1 = (double)atof(szreg1);
                    134:     x2 = (double)atof(szreg2);    
                    135: 
                    136:     switch (PendingOperation) {
                    137:         case '+':
                    138:            if (x2>(double)0) {          /* check for overflow */
                    139:                if (x1>(double)0) {
                    140:                     if (x1 > (MAXINT - x2))
                    141:                         fError = TRUE;
                    142:                     }
                    143:                 }
                    144:            else if (x2 < (double)0) {
                    145:                if (x1 < (double)0) {
                    146:                     if ( x1 < (MININT - x2))
                    147:                         fError = TRUE;
                    148:                     }
                    149:                 }
                    150:             if (!fError) {
                    151:                 result = x2 + x1;
                    152:                 }
                    153:             break;
                    154:         case '-':
                    155:            if (x2 < (double)0) {
                    156:                if (x1 > (double)0) {
                    157:                     if (x1 > (x2 - MININT))
                    158:                         fError = TRUE;
                    159:                     }
                    160:                  }
                    161:            else if (x2 > (double)0) {
                    162:                    if (x1 < (double)0) {
                    163:                         if (x1 < (x2 - MAXINT))
                    164:                             fError = TRUE;
                    165:                         }
                    166:                     }
                    167:             if (!fError) 
                    168:                 result = x2 - x1;
                    169:             break;
                    170:         case '/':
                    171:            if (x1 == (double)0.0)
                    172:                 fError = TRUE;
                    173:            else if (x2 > (double)0) {
                    174:                if (x1 > (double)0) {
                    175:                     if (x1 < (x2 / MAXINT))
                    176:                         fError = TRUE;
                    177:                     }
                    178:                 else {  /* x1 < 0 here */
                    179:                    if (x1 > (x2 / MININT))
                    180:                         fError = TRUE;
                    181:                    }
                    182:                 }
                    183:             else {  /* x2 < 0 here */
                    184:                if (x1 < (double)0) {
                    185:                     if (x1 > (x2 / MAXINT))
                    186:                         fError = TRUE;
                    187:                     }
                    188:                 else { /* x1 > 0 here */
                    189:                     if (x1 < (x2 / MININT))
                    190:                         fError = TRUE;
                    191:                     }
                    192:                 }
                    193:             if (!fError) result = x2 / x1;
                    194:             break;
                    195:         case '*':
                    196:            if (x1 == (double)0) return;
                    197:            if (ABS(x2) > (double)1) {
                    198:                if (ABS(x1) > (double)1) {
                    199:                     if (ABS(x1) > (MAXINT / ABS(x2)))
                    200:                         fError = TRUE;
                    201:                     } 
                    202:                 }                    
                    203:             if (!fError) result = x2 * x1; 
                    204:             break;
                    205:         }
                    206:     if (!fError) {
                    207:         strcpy(szreg1, ftoa((double)result));
                    208:         strcpy( szreg2, szreg1 );
                    209:         }
                    210:     Simplify();
                    211: }
                    212: 
                    213: VOID SquareRoot()
                    214: {
                    215:     double result;
                    216: 
                    217:     result = (double)atof(szreg1);
                    218:     if (result < 0.0) {
                    219:         fError = TRUE;
                    220:         return;
                    221:         }
                    222: 
                    223:     if ((result == 0.0) || ((lastkey == 'q') && (result == 1.0)))
                    224:         return;
                    225: 
                    226:     if ((result < (double) 1.00000002) && (result > (double) 1.0))
                    227:         result = (double)1.0;
                    228:     else
                    229:         result = sqrt(result);
                    230: 
                    231:     strcpy( szreg1, ftoa((double)result));
                    232: 
                    233:     if (atof( szreg1 ) == 0.0)
                    234:         strcpy(szreg1, "0.");
                    235: 
                    236:     Simplify();
                    237: }
                    238: 
                    239: VOID BinaryOperator( op )
                    240: CHAR op;
                    241: {
                    242:     if (fFirstOperand) {
                    243:         fFirstOperand = FALSE;
                    244:         strcpy(szreg2, szreg1);
                    245:         }
                    246:     else {
                    247:         Equilibrate();
                    248:         }
                    249:     PendingOperation = op;  
                    250: }
                    251: 
                    252: VOID Clear()
                    253: {
                    254:     fReadNumber = FALSE;
                    255:     fFirstOperand = TRUE;
                    256:     strcpy(szreg1, "0.");
                    257:     if (fError || lastkey == 'c'){ 
                    258:         strcpy(szreg2, "0.");
                    259:         PendingOperation = NULL;
                    260:         }
                    261:     fError = FALSE;
                    262: }
                    263: 
                    264:          /* trash out trailing zeros, if a '.' is in the number */
                    265:          /* and leading zeros in all cases. */
                    266: VOID Simplify()
                    267: {
                    268:     register int len;
                    269:     char local[20];
                    270:     register int count;
                    271: 
                    272:     count = 0;
                    273:     strcpy(local, szreg1);
                    274:     if (atof(local) != 0.0) {
                    275:         while (local[count++] == '0');
                    276:         strcpy(szreg1, &local[count-1] );
                    277:         }
                    278:     if (strchr(szreg1, '.')) {
                    279:         len = strlen(szreg1);
                    280:         while (szreg1[--len] == '0');
                    281:         szreg1[min(len + 1, 11)] = 0; /* null terminate */
                    282:         }
                    283: }
                    284: 
                    285: 
                    286: VOID DataXPaste()
                    287: {
                    288:     PSZ  lp;
                    289:     register char c;
                    290: 
                    291:     if (WinOpenClipbrd(NULL))
                    292:     {
                    293:        lp = (PSZ)WinQueryClipbrdData(NULL, CF_TEXT);
                    294:        if (lp)
                    295:         {
                    296:             while (*lp)
                    297:             {
                    298:                 c = tolower(*lp);
                    299:                 if (c == 'm')
                    300:                 {
                    301:                     lp++;
                    302:                     switch (tolower(*lp))
                    303:                     {
                    304:                     case '-':
                    305:                         c = '\271';
                    306:                         break;
                    307:                     case '+':
                    308:                         c = '\272';
                    309:                         break;
                    310:                     case 'r':
                    311:                         c = '\273';
                    312:                         break;
                    313:                     case 'c':
                    314:                         c = '\274';
                    315:                         break;
                    316:                     default:
                    317:                         c = ' ';
                    318:                         break;
                    319:                     }
                    320:                 }
                    321:                 lp++;
                    322:                 InterpretChar(c);
                    323:                 UpdateDisplay();
                    324:             }
                    325:         }
                    326:     }
                    327:     WinCloseClipbrd(NULL);
                    328:     InterpretChar('=');
                    329:     UpdateDisplay();
                    330: }
                    331: 
                    332: 
                    333: VOID DataXCopy()
                    334: {
                    335:     PSZ  lpsztext;
                    336: 
                    337:     if (WinOpenClipbrd(NULL))
                    338:     {
                    339:         WinEmptyClipbrd(NULL);
                    340:         DosAllocSeg(20, (SEL FAR *)&sel, 2L);  /* SEG_GETTABLE */
                    341:         if (sel == NULL) return;
                    342:        lpsztext = MAKEP(sel, 0);
                    343:         FarStrcpy(lpsztext, (PSZ)szreg1);
                    344:        WinSetClipbrdData(NULL, (ULONG)sel, CF_TEXT, CFI_SELECTOR);
                    345:         WinCloseClipbrd(NULL);
                    346:     }
                    347: }
                    348: 
                    349: 
                    350: VOID MPlus()
                    351: {
                    352:     double x2, x1, result;
                    353: 
                    354:     x2 = atof(szmem);
                    355:     x1 = atof(szreg1);
                    356: 
                    357:     if (x2>(double)0) {         /* check for overflow */
                    358:        if (x1>(double)0) {
                    359:             if (x1 > (MAXINT - x2))
                    360:                 fError = TRUE;
                    361:             }
                    362:         }
                    363:     else if (x2 < (double)0) {
                    364:        if (x1 < (double)0) {
                    365:             if ( x1 < (MININT - x2))
                    366:                 fError = TRUE;
                    367:             }
                    368:         }
                    369:     if (!fError) {
                    370:         result = x2 + x1;
                    371:         strcpy( szmem, ftoa((double)result));
                    372:         }
                    373:     if (result == (double)0.0)
                    374:          fValueInMemory = FALSE; 
                    375:     else fValueInMemory = TRUE;
                    376: }
                    377: 
                    378: VOID MClear()
                    379: {
                    380:      strcpy(szmem, "0.");   
                    381:      fValueInMemory = FALSE; 
                    382: }
                    383: 
                    384: 
                    385: VOID MMinus()
                    386: {
                    387:     double x1, x2, result;
                    388: 
                    389:     x2 = atof(szmem);
                    390:     x1 = atof(szreg1);
                    391:     if (x2 < (double)0) {
                    392:        if (x1 > (double)0) {
                    393:             if (x1 > (x2 - MININT))
                    394:                 fError = TRUE;
                    395:             }
                    396:          }
                    397:     else if (x2 > (double)0) {
                    398:            if (x1 < (double)0) {
                    399:                 if (x1 < (x2 - MAXINT))
                    400:                     fError = TRUE;
                    401:                 }
                    402:             }
                    403:     if (!fError) {
                    404:         result = x2 - x1;
                    405:         strcpy( szmem, ftoa((double)result));
                    406:         }
                    407:     if (result == (double)0.0)
                    408:          fValueInMemory = FALSE; 
                    409:     else fValueInMemory = TRUE;
                    410: }
                    411: 
                    412: VOID Evaluate( command )
                    413: BYTE command;
                    414: {
                    415:     currkey = command;
                    416:     switch( command ) {
                    417:         case '0': case '1': case '2': case '3': case '4': case '5':
                    418:         case '6': case '7': case '8': case '9': case '.': case 0xb1:
                    419:         case 'n': /* n = 'negate'  from keyboard */
                    420:             if ( fReadNumber ) {  
                    421:                 AppendNumber( command );
                    422:                 }
                    423:             else {
                    424:                       /* if starting a new number */
                    425:                 if (command != 0xb1)  
                    426:                     strcpy(szreg1, "0");
                    427:                 AppendNumber( command );
                    428:                 }
                    429:             if (command != 0xb1)  
                    430:                 fReadNumber = TRUE;
                    431:             break;
                    432:         case '+': case '-': case '/': case '*': case 'p':
                    433:             BinaryOperator(command);
                    434:             fReadNumber = FALSE;
                    435:             break;
                    436:         case '=':
                    437:             fReadNumber = FALSE;
                    438:             Equilibrate();
                    439:             PendingOperation = NULL;
                    440:             break;
                    441:         case 'q':
                    442:             SquareRoot();
                    443:             fReadNumber = FALSE;
                    444:             break;
                    445:         case 0xBB:   /* MR */
                    446:             strcpy(szreg1, szmem);
                    447:             fReadNumber = FALSE;
                    448:             Simplify();
                    449:             break;
                    450:         case 0xBA: /* M+ */
                    451:             MPlus();
                    452:             fReadNumber = FALSE;
                    453:             Simplify();
                    454:             break;
                    455:         case 0xB9: /* M- */
                    456:             MMinus();
                    457:             fReadNumber = FALSE;
                    458:             Simplify();
                    459:             break;
                    460:         case 0xBC:
                    461:             MClear(); /* MC */
                    462:             break;
                    463:         case '%':
                    464:             Percent();
                    465:             fReadNumber = FALSE;
                    466:             break;
                    467:         case 'c':
                    468:             Clear();
                    469:             break;
                    470:         }
                    471: }
                    472: 
                    473: VOID Percent()
                    474: {
                    475:     double x1, x2, result;
                    476: 
                    477:     x1 = atof(szreg1) / 100.0;
                    478:     x2 = atof(szreg2);
                    479:     if (ABS(x2) > (double)1) {
                    480:        if (ABS(x1) > (double)1) {
                    481:             if (x1 > (MAXINT / x2))
                    482:                 fError = TRUE;
                    483:             } 
                    484:         }                    
                    485:     if (!fError) {
                    486:         result = x2 * x1;
                    487:         strcpy( szreg1, ftoa((double)result));
                    488:         }
                    489:     Simplify();
                    490: }
                    491: 
                    492: VOID InitCalc()
                    493: {
                    494:     fReadNumber = FALSE;
                    495:     fError = FALSE;
                    496:     fFirstOperand = TRUE;
                    497:     PendingOperation = 0;
                    498:     strcpy(szreg1, "0.");
                    499:     strcpy(szmem,  "0.");
                    500: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.