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