⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 calculator.c

📁 嵌入式linux下的一个高级计算器程序的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
      // isolate the name of the user-defined variable      p1[0] = 0;      nam = (char*) malloc(strlen(ptr)+1);      strcpy(nam, ptr);      i = strlen(nam);      // remove blanks at end of variable name      while ((i > 0) && (nam[i] <= ' ')) {nam[i] = 0; i--;}      p1[0] = '=';      ptr = p1;      ptr++;      // ignore Spaces      i = 0;      while ((ptr[i] <= ' ') && ((unsigned int)i < strlen(formel)) ) i++;      if ((unsigned int)i < strlen(formel)) ptr += i;      // does Variable with this name already exists?      for (i = 0; i < cal->Vars; i++)        if (strcmp(cal->Var[i].Name, nam) == 0)           iVar = i;      // remember, that we should save the results in a user-defined       // variable      setvar = 1;      if (iVar >= 0) // Variable already exists, so deallocate the                      // new name        free(nam);      else if (cal->Vars < CALCULATOR_VARS-1) {        // create new user-defined variable        cal->Var[cal->Vars].Name = nam;        iVar = cal->Vars;        cal->Vars++;      }      else {        // already 99 Variables uses; need to free the longest unused        ilast = cal->RefCnt;        ip    =  -1;        for (i = 0; i < cal->Vars; i++) {          if (cal->Var[i].Ref < ilast) {            ip = i;            ilast = cal->Var[i].Ref;          }        }        if (ip >= 0) {          iVar = ip;          free(cal->Var[ip].Name);          cal->Var[ip].Name = nam;        }        else {          setvar = 0;          free(nam);        }      }    }  }  if (*iStack) {    // we have already found the first operand in a previous call, so now    // we first need a operator    if (strlen(ptr)) {      switch (ptr[0]) {      case '+':        OpStack[*iStack] = '+';        OpLvlStack[*iStack] = 2;        ptr++;        break;      case '-':        OpStack[*iStack] = '-';        OpLvlStack[*iStack] = 2;        ptr++;        break;      case '*':        OpStack[*iStack] = '*';        OpLvlStack[*iStack] = 3;        ptr++;        break;      case '/':        OpStack[*iStack] = '/';        OpLvlStack[*iStack] = 3;        ptr++;        break;      case '^':        OpStack[*iStack] = '^';        OpLvlStack[*iStack] = 4;        ptr++;        break;      default:        // no operator was found, so assume multyply        OpStack[*iStack] = '*';        OpLvlStack[*iStack] = 3;      }    }    // check, whether we can reduce the Stack a bit.    // If the current operator has a equal or lower level than the previous    // we can execute the last operation and replace the first operand with    // the result. This can be done until the level of the current operator    // is higher than the previous.    while ((*iStack > 1) && 	   (OpLvlStack[*iStack] <= OpLvlStack[*iStack-1])) {      switch (OpStack[*iStack-1]) {      case '+':        NumStack[*iStack-2] += NumStack[*iStack-1];        break;      case '-':        NumStack[*iStack-2] -= NumStack[*iStack-1];        break;      case '*':        NumStack[*iStack-2] *= NumStack[*iStack-1];        break;      case '/':        NumStack[*iStack-2] /= NumStack[*iStack-1];        if (!finite(NumStack[*iStack-2])) CalculatorError = ERR_DIVZERO;        break;      case '^':        NumStack[*iStack-2] = pow(NumStack[*iStack-2],NumStack[*iStack-1]);        break;      }      OpStack[*iStack-1] = OpStack[*iStack];      OpLvlStack[*iStack-1] = OpLvlStack[*iStack];      (*iStack)--;    }  }  // now look for an Operand  // ignore Spaces  i = 0;  while ((ptr[i] <= ' ') && ((unsigned int)i < strlen(ptr)) ) i++;  if ((unsigned int)i < strlen(ptr)) ptr += i;  // check the sign. Here is is not an operator  ksign = 1;  if (ptr[0] == '-'){    ksign = -1;    ptr++;  }  if (ptr[0] == '+'){    ksign = 1;    ptr++;  }  // check, whether the formula beginns here with a bracket  if (ptr[0] == '(') {    braces = 1;    ptr++;    // opening bracket was found, so look for the corresponding     // closing bracket    for (i = 0; (unsigned int)i <= strlen(ptr); i++) {      if (ptr[i] == '(') braces++;      if (ptr[i] == ')') braces--;      if ((braces == 0) || ((unsigned int)i == strlen(ptr))) {        // if no closing bracket was found, interprete the line 	// end as a closing bracket        last = ptr[i];        if ((unsigned int)i != strlen(ptr)) ptr[i] = 0;        NumStack[*iStack] = Calculator(ptr, cal) * (double) ksign;        ksign = 1;        if ((unsigned int)i != strlen(ptr)) ptr[i] = last;        ptr = &ptr[i+1];        break;      }    }    // ignore Spaces    i = 0;    while ((ptr[i] <= ' ') && ((unsigned int)i < strlen(ptr)) ) i++;    if ((unsigned int)i < strlen(ptr)) ptr += i;    // remember where we are in the formula    p1 = ptr;    p2 = ptr;  } else {    // there was no bracket, so look for a number    msign = ksign;    // find the operand    p1 = 0;    p2 = 0;    // sign is already determined, so remaining should begin with digits     // or a point it is not allowed to begin a number with the exponent!    // the decimal point is allowed to be input as a comma    if (((ptr[0] >= '0') && (ptr[0] <= '9')) || (ptr[0] == ',') || 	 (ptr[0] == '.')) {      // we have found a number, so find the end of the number (only       // mantissa).  Commas are now changed to the decimal point      p1 = ptr;      while (((p1[0] >= '0') && (p1[0] <= '9')) || (p1[0] == ',') || 	      (p1[0] == '.')) {        if (p1[0] == ',') p1[0] = '.';        p1++;      }            last = p1[0]; // remember the character, which ends the mantissa      p1[0] = 0;      sscanf (ptr, "%lf", &mantisse); // read in the mantissa      p1[0] = last;      if (toupper(last) == 'E') { // is the last character a exponent 	                          // indicator ?        p1++;        // check  sign of exponent        p2 = p1;        if (p2[0] == '-') {          p2++;          p1++;          esign = -1;        }        else if (p2[0] == '+') {          p2++;          p1++;          esign = 1;        }        // find end of exponent        while ((p2[0] >= '0') && (p2[0] <= '9')) p2++;                last = p2[0];        p2[0] = 0;        sscanf (p1, "%lf", &exponent);  // read in the exponent        mantisse = mantisse * pow(10,exponent*esign);        p2[0] = last;      }       // put the found number on the stack      NumStack[*iStack] = (double) msign * mantisse;    }    else {      // we have not found a number, so the formula may contain a variable       // or a function. The name of this allways has to begin with a       // character in the range [a..z] or [A..Z]      p1 = 0;      p2 = 0;      if (((ptr[0] >= 'a') && (ptr[0] <= 'z')) || 	  ((ptr[0] >= 'A') && (ptr[0] <= 'Z'))) {        p1 = ptr;        p1++;        // find the end of the name; names may contain the characters 	// [a..z] or [A..Z] or some digits.        while (((p1[0] >= 'a') && (p1[0] <= 'z')) || 	       ((p1[0] >= 'A') && (p1[0] <= 'Z')) || 	       ((p1[0] >= '0') && (p1[0] <= '9'))) p1++;        last = p1[0];  // remember the character, which separates the name         p1[0] = 0;        fkt = (char*) malloc(strlen(ptr)+1);        nam = (char*) malloc(strlen(ptr)+1);        strcpy(nam, ptr);        // internal functions are interpreted case insensitive, therefore 	// convert the searchstring to uppercase        for (i = 0; (unsigned int)i < strlen(ptr) +1; i++)          fkt[i] = toupper(ptr[i]);        p1[0] = last;        ifkt = 1;        // ---------- internal functions ----------------------------------------	// look in the table of internal constants/variables;	zfkt = -1;	while (fkt[0] == ' ') fkt++;	for (ii = 0; ii < INTERNCONS; ii++) {	  if (strstr(fkt, interncons[ii]) == fkt) {	    zfkt = ii;	    // change of ifkt to 0 indicates, that we have found and 	    // calculated  a function	    ifkt = 0;	    break;	  }	}	if (zfkt >= 0) {	  switch(zfkt) {	  case 0: //  "ANS"  copy the last result to the stack	    NumStack[*iStack] = (double) msign * CalculatorRes;	    break;	  case 1: //  "PI"   copy PI to the stack	    NumStack[*iStack] = (double) msign * CalculatorPI;	    break;	  }	  	} 	if (ifkt) {	  // look in the table of internal functions;	  zfkt = -1;	  while (fkt[0] == ' ') fkt++;	  for (ii = 0; ii < INTERNFKT; ii++) {	    if (strstr(fkt, internfkt[ii]) == fkt) {	      zfkt = internfktid[ii];	      // change of ifkt to 0 indicates, that we have found and 	      // calculated  a function	      ifkt = 0;	      break;	    }	  }	  // for real funktions increment p1 to take into account closing brackets	  if (zfkt >= 0) {	    switch(zfkt) {	    case 0: //  "LN"   natural logarithmus	      NumStack[*iStack] = (double) msign * 		log(FindBrackets(p1, &i, cal));	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 1: // "EXP"   power of e	      NumStack[*iStack] = (double) msign * 		exp(FindBrackets(p1, &i, cal));	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 2: //  "LOG10"  logarithmus of base 10	      NumStack[*iStack] = (double) msign * 		log10(FindBrackets(p1, &i, cal));	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 3: //  "LOG2"  logarithmus of base 2	      NumStack[*iStack] = (double) msign * 		log(FindBrackets(p1, &i, cal))/log(2.);	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 4: //  "LOG"  logarithmus of base N	      dummy = FindDualParam(p1, &i, cal, &basis);	      dummy = log(dummy)/log(basis);	      NumStack[*iStack] = (double) msign * dummy;	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 5: //  "ABS"  value without sign	      NumStack[*iStack] = (double) msign * 		fabs(FindBrackets(p1, &i, cal));	      break;	    case 6: //  "SQRT"  sqare root	      NumStack[*iStack] = (double) msign * 		sqrt(FindBrackets(p1, &i, cal));	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 7: //  "ATAN2" arcustanges with  two parameters for correct sign	      dummy = FindDualParam(p1, &i, cal, &basis);	      dummy = atan2(basis, dummy);	      if (CalculatorRad == 2)  // Degree		dummy *= 180./CalculatorPI;	      NumStack[*iStack] = (double) msign * dummy;	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 8: //  "SIGN"  return sign of number	      dummy = FindBrackets(p1, &i, cal);	      basis = dummy/fabs(dummy);	      NumStack[*iStack] = (double) msign * basis; 	      break;	    case  9: //  "AHSIN"  arcus sinus hyperbolicus	      dummy = FindBrackets(p1, &i, cal);	      dummy = asinh(dummy);	      if (CalculatorRad == 2)  // Degree		dummy *= 180./CalculatorPI;	      NumStack[*iStack] = (double) msign * dummy;	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 10: //  "ASIN"  arcus sinus 	      dummy = FindBrackets(p1, &i, cal);	      dummy = asin(dummy);	      if (CalculatorRad == 2)  // Degree		dummy *= 180./CalculatorPI;	      NumStack[*iStack] = (double) msign * dummy;	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 11: //  "HSIN"  sinus hyperbolicus	      dummy = FindBrackets(p1, &i, cal);	      if (CalculatorRad == 2)  // Degree		dummy *= CalculatorPI/180.;	      NumStack[*iStack] = (double) msign * sinh(dummy);	      break;	    case 12: //  "SIN"  sine	      dummy = FindBrackets(p1, &i, cal);	      if (CalculatorRad == 2)  // Degree		dummy *= CalculatorPI/180.;	      dummy = sin(dummy);	      if (fabs(dummy) < 1e-15) dummy = 0;	      NumStack[*iStack] = (double) msign * dummy;	      break;	    case 13: //  "AHCOS"  arcus cosinus hyperbolicus	      dummy = FindBrackets(p1, &i, cal);	      dummy = acosh(dummy);	      if (CalculatorRad == 2)  // Degree		dummy *= 180./CalculatorPI;	      NumStack[*iStack] = (double) msign * dummy;	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 14: //  "ACOS"  arcus cosinus	      dummy = FindBrackets(p1, &i, cal);	      dummy = acos(dummy);	      if (CalculatorRad == 2)  // Degree		dummy *= 180./CalculatorPI;	      NumStack[*iStack] = (double) msign * dummy;	      if (!finite(NumStack[*iStack])) CalculatorError = ERR_DOMAIN;	      break;	    case 15: //  "HCOS"  cosinus hyperbolicus	      dummy = FindBrackets(p1, &i, cal);	      if (CalculatorRad == 2)  // Degree		dummy *= CalculatorPI/180.;	      NumStack[*iStack] = (double) msign * cosh(dummy);	      break;	    case 16: //  "COS"  cosinus	      dummy = FindBrackets(p1, &i, cal);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -