📄 calculator.c
字号:
if (CalculatorRad == 2) // Degree dummy *= CalculatorPI/180.; dummy = cos(dummy); if (fabs(dummy) < 1e-15) dummy = 0; NumStack[*iStack] = (double) msign * dummy; break; case 17: // "AHTAN" arcus tangens hyperbolicus dummy = FindBrackets(p1, &i, cal); dummy = atanh(dummy); if (CalculatorRad == 2) // Degree dummy *= 180./CalculatorPI; NumStack[*iStack] = (double) msign * dummy; if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 18: // "ATAN" arcus tangens dummy = FindBrackets(p1, &i, cal); dummy = atan(dummy); if (CalculatorRad == 2) // Degree dummy *= 180./CalculatorPI; NumStack[*iStack] = (double) msign * dummy; if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 19: // "HTAN" tangens hyperbolicus dummy = FindBrackets(p1, &i, cal); if (CalculatorRad == 2) // Degree dummy *= CalculatorPI/180.; NumStack[*iStack] = (double) msign * tanh(dummy); if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 20: // "TAN" tangens dummy = FindBrackets(p1, &i, cal); if (CalculatorRad == 2) // Degree dummy *= CalculatorPI/180.; NumStack[*iStack] = (double) msign * tan(dummy); if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 21: // "AHSEC" arcus secant hyperbolicus dummy = FindBrackets(p1, &i, cal); dummy = 1./dummy; dummy = acosh(dummy); if (CalculatorRad == 2) // Degree dummy *= 180./CalculatorPI; NumStack[*iStack] = (double) msign * dummy; if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 22: // "ASEC" arcus secant dummy = FindBrackets(p1, &i, cal); dummy = 1./dummy; dummy = acos(dummy); if (CalculatorRad == 2) // Degree dummy *= 180./CalculatorPI; NumStack[*iStack] = (double) msign * dummy; if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 23: // "HSEC" tangens hyperbolicus dummy = FindBrackets(p1, &i, cal); if (CalculatorRad == 2) // Degree dummy *= CalculatorPI/180.; NumStack[*iStack] = (double) msign * 1. /cosh(dummy); if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 24: // "SEC" tangens dummy = FindBrackets(p1, &i, cal); if (CalculatorRad == 2) // Degree dummy *= CalculatorPI/180.; NumStack[*iStack] = (double) msign * 1./cos(dummy); if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 25: // "AHCOT" arcus secant hyperbolicus dummy = FindBrackets(p1, &i, cal); dummy = 1./dummy; dummy = atanh(dummy); if (CalculatorRad == 2) // Degree dummy *= 180./CalculatorPI; NumStack[*iStack] = (double) msign * dummy; if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 26: // "ACOT" arcus secant dummy = FindBrackets(p1, &i, cal); dummy = 1./dummy; dummy = atan(dummy); if (CalculatorRad == 2) // Degree dummy *= 180./CalculatorPI; NumStack[*iStack] = (double) msign * dummy; if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 27: // "HCOT" tangens hyperbolicus dummy = FindBrackets(p1, &i, cal); if (CalculatorRad == 2) // Degree dummy *= CalculatorPI/180.; NumStack[*iStack] = (double) msign * 1. /tanh(dummy); if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 28: // "COT" tangens dummy = FindBrackets(p1, &i, cal); if (CalculatorRad == 2) // Degree dummy *= CalculatorPI/180.; NumStack[*iStack] = (double) msign * 1./tan(dummy); if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 29: // "AHCSC" arcus secant hyperbolicus dummy = FindBrackets(p1, &i, cal); dummy = 1./dummy; dummy = asinh(dummy); if (CalculatorRad == 2) // Degree dummy *= 180./CalculatorPI; NumStack[*iStack] = (double) msign * dummy; if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 30: // "ACSC" arcus secant dummy = FindBrackets(p1, &i, cal); dummy = 1./dummy; dummy = asin(dummy); if (CalculatorRad == 2) // Degree dummy *= 180./CalculatorPI; NumStack[*iStack] = (double) msign * dummy; if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 31: // "HCSC" tangens hyperbolicus dummy = FindBrackets(p1, &i, cal); if (CalculatorRad == 2) // Degree dummy *= CalculatorPI/180.; NumStack[*iStack] = (double) msign * 1. /sinh(dummy); if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; case 32: // "CSC" tangens dummy = FindBrackets(p1, &i, cal); if (CalculatorRad == 2) // Degree dummy *= CalculatorPI/180.; NumStack[*iStack] = (double) msign * 1./sin(dummy); if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN; break; } p1 += i; } } if (ifkt) { // ---------- user-defined variables ------------ // we have not found any internal function, so look wether it // is a user-defined variable // user-defined variables are case sensitive for (j = 0; j < cal->Vars; j++) { if (strcmp(nam, cal->Var[j].Name) == 0) { NumStack[*iStack] = (double) msign * cal->Var[j].Valu; cal->Var[j].Ref = cal->RefCnt++; ifkt = 0; break; } } } if (ifkt) { // ---------- user-defined functions ------------ // we have also not found any user-defined variable, so look // for user-defined functions // user-defined functions are case sensitive for (j = 1; j <= CalculatorFktAnz; j++) { if (strcmp(CalculatorFkt[j].Name, nam) == 0) { dummy = CalculateFkt(p1, &i, &CalculatorFkt[j]); ifkt = 0; NumStack[*iStack] = (double) msign * dummy; p1 +=i; } } } free(fkt); free(nam); if (ifkt) { // Syntax Error, we have found an unknown name, probably // because of a typing error CalculatorError = ERR_UNKNOWN; return 1./CalculatorZero; } } else { // Illegal characters: there have been characters, which do // not give a allowable name CalculatorError = ERR_ILLEGAL; return 1./CalculatorZero; } } // End: check for functions or Variables } // End: find Operand if (p1 > ptr) ptr = p1; if (p2 > ptr) ptr = p2; // ignore Spaces i = 0; while ((ptr[i] <= ' ') && ((unsigned int)i < strlen(ptr)) ) i++; if ((unsigned int)i < strlen(ptr)) ptr += i; // we have remaining characters in the formula, so try again if (strlen(ptr) > 0) { (*iStack)++; // calculate or put on stack the remainder of the formula; // the result is ignored here, because it is put on the stack dummy = Calculator_Sub(ptr, NumStack, OpStack, OpLvlStack, iStack, cal); // ignore Spaces i = 0; while ((ptr[i] <= ' ') && ((unsigned int)i < strlen(ptr)) ) i++; if ((unsigned int)i < strlen(ptr)) ptr += i; } // we are at the end of the formula, so calculate everything // on the stack while (*iStack) { switch (OpStack[*iStack]) { case '+': NumStack[*iStack-1] += NumStack[*iStack]; break; case '-': NumStack[*iStack-1] -= NumStack[*iStack]; break; case '*': NumStack[*iStack-1] *= NumStack[*iStack]; break; case '/': NumStack[*iStack-1] /= NumStack[*iStack]; if (!finite(NumStack[*iStack-1])) CalculatorError = ERR_DIVZERO; break; case '^': NumStack[*iStack-1] = pow(NumStack[*iStack-1],NumStack[*iStack]); break; case '.': break; } (*iStack)--; } // should we store the result in a user-defined variable? if (setvar) { cal->Var[iVar].Valu = NumStack[*iStack]; cal->Var[iVar].Ref = cal->RefCnt++; } // return the current value return NumStack[*iStack];}double Calculator(char *formel, CALCFKT *cal) // // This subroutine is used to calculate a formula. // The subroutine provides the calculation routine "Calculator_sub" // with an individual Numerik stack, so that formulas embedded in // other formulas (for example argument lists of functions) can be // evaluated. // // formel: formula to evaluate // *cal: pointer to global variables{ double NumStack[100]; char OpStack[100]; char OpLvlStack[100]; int iStack = 0; double res; int i, j, ifkt; char *frml, *ptr, *p1, *p2; CALCFKT *var; // user-defined variables get a timestamp, so that unused variables // can be deleteD to get space for new definitions if (cal->RefCnt > 10000000) { cal->RefCnt -= 5000000; for (i = 0; i < cal->Vars; i++) { cal->Var[i].Ref -= 5000000; if (cal->Var[i].Ref < 0) cal->Var[i].Ref = 0; } } frml = formel; while (frml[0] == ' ') frml++; // do we need to define a user-defined function ? ptr = strstr(frml, ":="); // Definition of a Function if (ptr) { ptr[0] = 0; // there must be the definition of a parameterlist p1 = strchr(frml, '('); if (!p1) { // Error: Syntax for Funktion definition CalculatorError = ERR_FPARAM; return 1./CalculatorZero; } // remove spaces at end of string p1[0] = 0; i = strlen(frml); while ((i > 0) && (frml[i] <= ' ')) frml[i--] = 0; if (CalculatorFktAnz < CALCULATOR_FKT) { // append the function to the functionlist CalculatorFktAnz++; ifkt = CalculatorFktAnz; for (i = 1; i < CalculatorFktAnz; i++) { if (strcmp(CalculatorFkt[i].Name, frml) == 0) { ifkt = i; // Funktion with this name already exists // free the variables used for the old definition for (j = 0; j < CalculatorFkt[i].Vars; j++) free(CalculatorFkt[i].Var[j].Name); CalculatorFktAnz--; CalculatorFkt[i].Vars = 0; free(CalculatorFkt[i].Name); free(CalculatorFkt[i].Def); break; } } // create variables for new definition var = &CalculatorFkt[ifkt]; var->Name = (char*) malloc(strlen(frml)+1); strcpy(var->Name, frml); var->Def = (char*) malloc(strlen(ptr+2)+1); strcpy(var->Def, ptr+2); // isolate the local variables for the parameter-list p1++; p2 = strchr(p1, ';'); if (!p2) p2 = strchr(p1, ')'); while (p2) { p2[0] = 0; while (p1[0] == ' ') p1++; i = strlen(p1); while ((i > 0) && (p1[i] <= ' ')) p1[i--] = 0; var->Var[var->Vars].Name = (char*) malloc(strlen(p1)+1); strcpy(var->Var[var->Vars].Name, p1); var->Vars++; p1 = p2; p1++; p2 = strchr(p1, ';'); if (!p2) p2 = strchr(p1, ')'); } return 0; } else { CalculatorError = ERR_FKTANZ; return 0; } } // End: define Function // no function definiton, so evaluate the formula CalculatorLevel++; // in case of recursive calls, we need a indication // for the initial level res = Calculator_Sub(formel, &NumStack[0], OpStack, OpLvlStack, &iStack, cal); CalculatorLevel--; if (CalculatorLevel == 0) { // we are back at level 0, so the formula // is evaluated if (!CalculatorError) { CalculatorRes = res; // if no errors appeared, remember the // last result cal->last = res; // add the result to the result-history list, if it is different // from the previous if ( res != CalculatorHistory[CalculatorHistCnt-1]) { if (CalculatorHistCnt == CALCULATOR_HISTORY) { // no room for further history entries, so remove the oldest. for (i = 0; i < CALCULATOR_HISTORY-1; i++) CalculatorHistory[i] = CalculatorHistory[i+1]; CalculatorHistCnt--; } CalculatorHistory[CalculatorHistCnt] = res; CalculatorHistCnt++; } } } return res;}double Calculate_Formula(char *formel) // // This subroutine is a easy to use function to calculate a formula. // // formel: formula to evaluate{ return Calculator(formel, &CalculatorFkt[0]);}// Local Variables: ***// mode:c++ ***// End: ***
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -