Annotation of os232sdk/toolkt20/c/samples/calc/calcmath.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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