|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.