📄 calculator.c
字号:
}voidWriteHistory (FILE *config){ char last; char *ptr; int i, j; if (config) { fprintf (config, "[REF]\n"); // save last timestamp fprintf (config, "%d\n", CalculatorFkt[0].RefCnt); fprintf (config, " radian=%d\n", CalculatorRad); fprintf (config, " format=%d\n", CalculatorFmt); fprintf (config, " autoans=%d\n", CalculatorAutoAns); fprintf (config, " autohighlight=%d\n", CalculatorAutoHighlight); fprintf (config, "[VAR]\n"); // save user-defined variables for (i = 0; i < CalculatorFkt[0].Vars; i++) { fprintf (config, "%s;%18.12g;%d\n", CalculatorFkt[0].Var[i].Name, CalculatorFkt[0].Var[i].Valu, CalculatorFkt[0].Var[i].Ref); } fprintf (config, "[HIST]\n"); // save formula history for (i = 0; i < CalculatorCmdHistoryAnz; i++) { ptr = CalculatorCmdHistory[i]; j = strlen(ptr); while((j > 0) && ((ptr[j] <= ' ') || ((unsigned)ptr[j] >= 0x80))) {ptr[j] = 0; j--;} if (strlen(CalculatorCmdHistory[i]) < 255) { if (strlen(CalculatorCmdHistory[i]) > 0) fprintf (config, "%s\n", CalculatorCmdHistory[i]); } else { // line too long, break into several lines ptr = CalculatorCmdHistory[i]; while (ptr) { if (strlen(ptr) > 255) { last = ptr[255]; // more lines needed, append continuation char fprintf(config, "%s\\\n", ptr); ptr[255] = last; ptr = &ptr[255]; } else { // no more continuation lines needed fprintf(config, "%s\n", ptr); ptr = NULL; } } } } fprintf (config, "[FKT]\n"); // save user-defined functions for (i = 1; i <= CalculatorFktAnz; i++) { // function name and number of parameters fprintf(config, " <%s> %d\n", CalculatorFkt[i].Name, CalculatorFkt[i].Vars); for (j = 0; j < CalculatorFkt[i].Vars; j++) // parameter names fprintf(config, " <%s>\n", CalculatorFkt[i].Var[j].Name); if (strlen(CalculatorFkt[i].Def) < 255) // function definition fits in one line fprintf (config, "%s\n", CalculatorFkt[i].Def); else { ptr = CalculatorFkt[i].Def; // break definition into shorter lines with continuation char while (ptr) { if (strlen(ptr) > 255) { last = ptr[255]; fprintf(config, "%s\\\n", ptr); ptr[255] = last; ptr = &ptr[255]; } else { fprintf(config, "%s\n", ptr); ptr = NULL; } } } } fprintf (config, "[VHIST]\n"); // read the result history for (i = 0; i < CalculatorHistCnt; i++) fprintf (config, "%18.12g\n", CalculatorHistory[i]); }}doubleFindBrackets(char *text, int *end, CALCFKT *cal) // // Find the brackets which surround the parameter of a funtion and // evaluate the parameter as a formula. // // text: parameter to examine; this parameter can be a formula // *end: pointer to the end of the paramter // *cal: pointer to the global variables list // { unsigned int i, j, braces, lineend; char *ptr; char last; double res; ptr = text; // first ignore leeding Spaces, return if no formula at al. i = 0; while ((ptr[i] <= ' ') && (i < strlen(ptr)) ) i++; if (i == strlen(ptr)) { CalculatorError = ERR_NOBRACKET; return 0.; } // now the first character must be a opening bracket if (ptr[i] == '(') { braces = 1; // look for the closing bracket; there may by ohter opening // brackets, so look for the matching closing bracket for (j = i+1; j <= strlen(ptr); j++) { if (ptr[j] == '(') braces++; if (ptr[j] == ')') braces--; if ((braces == 0) || (j == strlen(ptr))) { // we have found the closing bracket or there are not // enough closing brackets. In the later case we // set the line-end as the position of the closing // bracket. last = ptr[j]; lineend = 0; if (j != strlen(ptr)) lineend = 1; if (lineend) ptr[j] = 0; // find the value of the paramter res = Calculator(&ptr[i+1], cal); // tell the calling subroutine, up to where we have // analized the formula *end = j; if (lineend) { ptr[j] = last; *end = j+1; } return res; } } } // we have not found the opening bracket, there is no valid // parameter list! CalculatorError = ERR_BRACKETMIS; return 1./CalculatorZero;}doubleFindDualParam(char *text, int *end, CALCFKT *cal, double *pa1) // // Find the brackets which surround the parameter of a funtion and // evaluate 2 parameters separated by ';' as a formula. // // text: parameter to examine; this parameter can be a formula // *end: pointer to the end of the paramter // *cal: pointer to the global variables list // *pa1: value of first parameter // { unsigned int i, j, braces, lineend; char *ptr, *p1; char last; double res; ptr = text; // first ignore leeding Spaces, return if no formula at al. i = 0; while ((ptr[i] <= ' ') && (i < strlen(ptr)) ) i++; if (i == strlen(ptr)) { CalculatorError = ERR_NOBRACKET; return 0.; } // now the first character must be a opening bracket if (ptr[i] == '(') { braces = 1; // look for the closing bracket; there may by ohter opening // brackets, so look for the matching closing bracket for (j = i+1; j <= strlen(ptr); j++) { if (ptr[j] == '(') braces++; if (ptr[j] == ')') braces--; if ((braces == 0) || (j == strlen(ptr))) { // we have found the closing bracket or there are not // enough closing brackets. In the later case we // set the line-end as the position of the closing // bracket. last = ptr[j]; lineend = 0; if (j != strlen(ptr)) lineend = 1; if (lineend) ptr[j] = 0; p1 = strchr(&ptr[i+1], ';'); if (!p1) { CalculatorError = ERR_PARANZ; return 0.; } p1[0] = 0; // find the value of the paramter *pa1 = Calculator(&ptr[i+1], cal); res = Calculator(&p1[1], cal); p1[0] = ';'; // tell the calling subroutine, up to where we have // analized the formula *end = j; if (lineend) { ptr[j] = last; *end = j+1; } return res; } } } // we have not found the opening bracket, there is no valid // parameter list! CalculatorError = ERR_BRACKETMIS; return 1./CalculatorZero;}doubleCalculateFkt(char *text, int *end, CALCFKT *cal) // // Calculate a user-define function. // - Find the brackets which surround the parameterlist // - separate the parameters // - treat every parameter as formula and calculate it. // - calculate the user-defined fuction by applying the parameterlist // // text: parameterlist to examine; parameters are separated by ";" // the parameterlist is enclosed by brackets // *end: pointer to the end of the paramterlist // *cal: pointer to the global variables list // { unsigned int i, j, braces; int ivar; char *ptr, *p1, *p2, *sub, lineend, fktend; double res; ptr = text; lineend = 0; fktend = 0; ivar = 0; p2 = NULL; // first ignore leeding Spaces, return if no formula at al. i = 0; while ((ptr[i] <= ' ') && (i < strlen(ptr)) ) i++; if (i == strlen(ptr)) { CalculatorError = ERR_PREEND; return 0.; } // now the first character must be a opening bracket if (ptr[i] == '(') { p1 = &ptr[i+1]; while (!fktend) { // look for parameter separator p2 = strchr(p1, ';'); if (!p2) { // look for the closing bracket; there may by other opening // brackets, so look for the matching closing bracket braces = 1; for (j = 0; j <= strlen(p1); j++) { if (p1[j] == '(') braces++; if (p1[j] == ')') braces--; if ((braces == 0) || (j == strlen(p1))) { // we have found the closing bracket or there are not // enough closing brackets. In the later case we // set the line-end as the position of the closing // bracket. fktend = 1; if (j == strlen(p1)) lineend = 1; p2 = &p1[j]; break; } } } // prepare one parameter for evaluation p2[0] = 0; // copy the formula to a local variable, because // the routine Calculator destroyes the string sub = (char*)malloc(strlen(p1)+1); strcpy(sub, p1); // evaluate the substring res = Calculator(sub, &CalculatorFkt[0]); free(sub); // if there is an error int the formula, stop here if (CalculatorError) return 1./CalculatorZero; cal->Var[ivar].Valu = res; ivar++; if (ivar > cal->Vars) { // there are more Parameters than // defined in the function definition CalculatorError = ERR_TOOMUCH; return 1./CalculatorZero; } // go to the next parameter if (!lineend) { p1 = p2; p1++; } } // tell the calling subroutine, up to where we have // analized the formula if (!lineend) p2++; *end = (int) (p2 - text); // copy the function definition to a local variable, because // the routine Calculator destroyes the string sub = (char*) malloc(strlen(cal->Def)); strcpy(sub, cal->Def); // Calculate the function and return the result res = Calculator(sub, cal); free (sub); return res; } // if we arrive here, there were no parameters to evaluate. CalculatorError = ERR_NOARG; return 1./CalculatorZero; }double Calculator_Sub (char *formel, double *NumStack, char *OpStack, char *OpLvlStack, int *iStack, CALCFKT *cal) // // core subroutine for evaluation of formulas // // The formula string is examined from the left side. The first call // to this subroutine looks for the first operand. The following calls // first look for an operator and the for a second operand. After this // it calls itself with the remaining part of the formula. // // formel: string with the formula // NumStack: numerical Stack of Operands // OpStack: Stack of Operators // OpLvlStack: weight of Operators in OpStack // iStack: current Stack position // *cal: pointer to global variables //{ char *ptr, *p1, *p2, *fkt, *nam; char last; int i, j, msign, esign, ksign, braces, setvar, iVar, ilast, ip, ifkt, zfkt, ii; double mantisse, exponent, dummy, basis; // check if formula is valid ptr = formel; if (ptr == NULL) { CalculatorError = ERR_PREEND; return 0.; } // remove blanks at end of formula, // if nothing remains there is no valid formula i = strlen(ptr)-1; while((i>0) && (ptr[i] <= ' ')) { ptr[i] = 0; i--; } if (strlen(ptr) == 0) { CalculatorError = ERR_PREEND; return 0.; } // ignore trailing blanks i = 0; while (( ptr[i] <= ' ') && ((unsigned int)i < strlen(formel)) ) i++; if ((unsigned int)i < strlen(formel)) ptr += i; // initialize sign-indicators for positive values. msign = 1; esign = 1; iVar = -1; setvar = 0; if (!*iStack) { // Check, whether we should copy the formula result to a user-defined // variable this can only happen, if no other action was performed on // the formula (iStack == 0) p1 = strchr(ptr, '='); if (p1) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -