int calcExpression(char * p) { // if p = #: return atoi(p) // // else: // L = P.LeftSide // O = P.Op // R = P.RightSide // return PerformOp(calcExpression(L), calcExpression(R), O) // ACTUAL FUNCTION // if p is a number, return it if (isNumber(p)) return atoi(p); // Get Left, Right and Op from p. char leftOperand[256] = ""; char rightOperand[256]= ""; char op; int leftOpIndex = getLeftOperand(p, leftOperand); int operatorIndex = getOperator(p, leftOpIndex, &op); int rightOpIndex = getRightOperand(p+operatorIndex, rightOperand); printf("%s, %c, %s", leftOperand, op, rightOperand); getchar(); if (isEmpty(rightOperand)) return calcExpression(leftOperand); return performOperator( calcExpression(leftOperand), calcExpression(rightOperand), op ); }
int fillRegArray(void) { char charKey; linelist ln=regTab.strings; int lineNum=0; double mass,width; char invStr[STRSIZ], massStr[STRSIZ], widthStr[STRSIZ]; inireg_(); while (ln != NULL) { int power=0; char lv[PLISTLEN]=""; invStr[1]=0; massStr[0]=0; widthStr[0]=0; lineNum++; sscanf(ln->line,"%[^|]%*c%[^|]%*c%[^|]%*c%d",invStr+1,massStr,widthStr,&power); /*============ Invariant ===========*/ trim(invStr+1); invStr[0]='S'; if( !checkPhysVal(invStr,&charKey, lv) ) { sprintf(errorText," Error in regularization table line %d .\n" " Wrong field 'Momentum' .",lineNum); goto errorExit; } coninv_(lv); /*================ Mass ============*/ if( calcExpression(massStr,rd_numW,&mass) ) { sprintf(errorText," Error in regularization table line %d .\n" " Wrong field 'Mass' .",lineNum); goto errorExit; } /*==================Width ==========*/ if( calcExpression(widthStr,rd_numW,&width) ) { sprintf(errorText," Error in regularization table line %d .\n" " Wrong field 'Width' .",lineNum); goto errorExit; } /*============ Power ===============*/ if( power<1 ||power>2 ) { sprintf(errorText," Error in regularization table line %d .\n" " Power is out of range.",lineNum); goto errorExit; } addreg_(lv,mass,width,power); ln=ln->next; } return 0; errorExit: messanykey(2,10,errorText); return 1; }
int wrt_hist2(FILE *fi, char * comment) { int i,nameL1,nameL2; linelist ll; char minRec1[200],minRec2[200],maxRec1[200],maxRec2[200],nameRec1[200],nameRec2[200]; if(comment) fprintf(fi,"%s\n",comment); else fprintf(fi,"\n"); if(!(fi)) return; fprintf(fi,"%s\n",histTab.mdlName); fprintf(fi,"%s\n",histTab.headln); sscanf(histTab.format,"%[^|]|%*[^|]|%*[^|]|%[^|]",nameRec1,nameRec2 ); nameL1=strlen(nameRec1); nameL2=strlen(nameRec2); fprintf(fi,"%s|> Min_1 <|> Max_1 <|%s|> Min_1 <|> Max_1 <|\n",nameRec1,nameRec2); for(ll=histTab.strings;ll;ll=ll->next) { double V; char buff[20]; sscanf(ll->line,"%[^|]|%[^|]|%[^|]|%[^|]|%[^|]|%[^|]", nameRec1,minRec1,maxRec1,nameRec2,minRec2,maxRec2); fprintf(fi,"%s|", nameRec1); calcExpression(minRec1,rd_num,&V); sprintf(buff,"%E",V); fprintf(fi,"%15.15s|", buff); calcExpression(maxRec1,rd_num,&V); sprintf(buff,"%E",V); fprintf(fi,"%15.15s|", buff); fprintf(fi,"%s|", nameRec2); trim(nameRec2); if(strlen(nameRec2)==0) fprintf(fi," |\n"); else { calcExpression(minRec2,rd_num,&V); sprintf(buff,"%E",V); fprintf(fi,"%15.15s|", buff); calcExpression(maxRec2,rd_num,&V); sprintf(buff,"%E",V); fprintf(fi,"%15.15s\n", buff); } } for(i=0;i<nameL1+nameL1+60;i++) fprintf(fi,"="); fprintf(fi,"\n"); /* writetable0(&histTab,nchan); */ writeDistributions(fi); return 0; }
static void f8_key_prog(int x) { static char FUNC[75]="2*2 % Press ESC to finish, F1 for help, ENTER to calculate"; int npos=1; void * pscr; get_text(1,20,80,21,&pscr); scrcolor(Red,White); goto_xy(1,20); print("CALC : "); goto_xy(1,21); print("result="); scrcolor(Black,White); for(;;) { double res; int err; int key; goto_xy(9,20); key=str_redact(FUNC,npos,70); if(key==KB_ESC) break; else if(key==KB_F1) show_help("n_calc"); else if(key==KB_ENTER) { goto_xy(8,21); err=calcExpression(FUNC,rd_num,&res); goto_xy(9,21); if(err) {print("Erorr: %s",errmesstxt(err)); npos=rderrpos;} else print("%E ",res); } } put_text(&pscr); }
int main() { char in[256]; while(1) { // Read input from user getInput(in); if (strncmp(in, "quit", 4) == 0) break; // Perform calculations int result = calcExpression(in); printf("%d\n", result); } }
int main(void) { fprintf(stdout, "Type math expession:\n"); Lexer *exp = (Lexer *) malloc(sizeof(Lexer)); initMathExpression(exp); MathResult result = calcExpression(exp); if (result.err != NOTHING) { // show place of error showErr(result.err, experrorPointer, stderr); clearMathExpression(exp); return 1; } printf("Result = %g\n", result.value); clearMathExpression(exp); free(exp); return 0; }
/*! * Вычисляет значение функции с конкретными значениями переменных * \param[in] current - Разбор дерева выражения * \param[in] variantValue – Список конкретных значений для каждой переменной * \return - Результат вычисления */ long long calcExpression(exprNode* current, QMap<QString, long long> variantValue) { QMap<QString, long long>::iterator i; switch (current->type) { //1.1. Если данный узел содержит константу, то вернуть само это значение. case const1: { return current->numbervalue; } //1.2. Если данный узел содержит переменную, то вернуть значение этой переменной, которое берется из списка variantValue. case var1: return variantValue.value(current->namevar); //1.3. Если данный узел содержит оператор, то выполнить вычисление по этому оператору с результатами дочернего узла и возвращает это значение. case plus1: //Сложение return calcExpression(current->leftOperand, variantValue) + calcExpression(current->rightOperand, variantValue); case minus: //Вычитание return calcExpression(current->leftOperand, variantValue) - calcExpression(current->rightOperand, variantValue); case multi: //Умножение return calcExpression(current->leftOperand, variantValue) * calcExpression(current->rightOperand, variantValue); case divide: //Деление { int y=calcExpression(current->rightOperand, variantValue); // Ошибки. Если в операции деления делитель является нулем if (y == 0) { QString message; QString lineValue; for (i = variantValue.begin(); i != variantValue.end(); ++i) lineValue += (i.key()+ "="+QString::number(i.value())+", "); if (lineValue.size() == 0) message = "В процессе вычисления произошло деление на ноль"; else message = "При переменных "+lineValue+"в процессе вычисления произошло деление на ноль"; throw (message); } return llround(calcExpression(current->leftOperand, variantValue) / y); } case mod: //Получение остатка от деления return calcExpression(current->leftOperand, variantValue) % calcExpression(current->rightOperand, variantValue); case prefixInc: //Префиксный инкремент return calcExpression(current->leftOperand, variantValue) +1; case postfixInc: //Постфиксный инкремент return calcExpression(current->leftOperand, variantValue); case prefixDec: //Префиксный декремент return calcExpression(current->leftOperand, variantValue) - 1; case postfixDec: //Постфиксный декремент return calcExpression(current->leftOperand, variantValue); case assignment: //Присваивание { variantValue[current->leftOperand->namevar] = calcExpression(current->rightOperand, variantValue); return variantValue[current->leftOperand->namevar]; } case addAssign: //Присваивание со сложением { variantValue[current->leftOperand->namevar] += calcExpression(current->rightOperand, variantValue); return variantValue[current->leftOperand->namevar]; } case subAssign: //Присваивание с вычитанием { variantValue[current->leftOperand->namevar] -= calcExpression(current->rightOperand, variantValue); return variantValue[current->leftOperand->namevar]; } case multiAssign: //Присваивание с умножением { variantValue[current->leftOperand->namevar] *= calcExpression(current->rightOperand, variantValue); return variantValue[current->leftOperand->namevar]; } case divideAssign: //Присваивание с делением { int y = calcExpression(current->rightOperand, variantValue); // Ошибки. Если в операции деления делитель является нулем if (y == 0) { QString message; QString lineValue; QMap<QString, long long>::iterator endOfValue = variantValue.end(); //отимизация for (i = variantValue.begin(); i != endOfValue; ++i) lineValue += (i.key() + "=" + QString::number(i.value()) + ", "); if (lineValue.size() == 0) message = "В процессе вычисления произошло деление на ноль"; else message = "При переменных " + lineValue + "в процессе вычисления произошло деление на ноль"; throw (message); } variantValue[current->leftOperand->namevar] = llround(variantValue.value(current->leftOperand->namevar) / y); return variantValue[current->leftOperand->namevar]; } case abs1: //Вычисление модуля return abs(calcExpression(current->leftOperand, variantValue)); case pow1: //Возведение в степень return pow(calcExpression(current->leftOperand,variantValue), calcExpression(current->rightOperand,variantValue)); case sqrt1: // Извлечение квадратного корня return llround(sqrt(calcExpression(current->leftOperand, variantValue))); case fmax1: //Наибольшее значение среди двух значений return fmax(calcExpression(current->leftOperand, variantValue), calcExpression(current->rightOperand, variantValue)); case fmin1: //Наименьшее значение среди двух значений return fmin(calcExpression(current->leftOperand, variantValue), calcExpression(current->rightOperand, variantValue)); } //2. Переход вверх : заполнить возвращенный результат для вычисления значения родительского узла. //3. Конечный результат: возвращаемое значение для корня дерева. }
bool compareExpression(QMap<QString, DataVariable>& listVar, exprNode* expr1, exprNode* expr2, QList< QMap< QString, DataVariable >>& listRange) { bool equivalent=true; //флаг эквивалентности int n = listVar.size(); //количество эелементы в listVar QMap<QString, long long> variantValue; //список переменные с конкретными значенями QMap<QString, DataVariable>::Iterator itempValue; //интератор на listVar QMap<QString, DataVariable> tempValues; //временный список переменные и их пределы QMap<QString, long long>::Iterator temp; //интератор на variantValue bool lastCombination = false; // флаг lastCombination, который отмечает является ли текущая комбинация последней DataVariable tempRange; itempValue = listVar.begin(); int i; //1.3.Заполнить все переменные в listVar на variantValue с помощью интератор itempValue, их начальные значения будут являться itempValue.value().lowEdge. for (i = 1; i <= n; i++) { variantValue.insert(itempValue.key(), itempValue.value().lowEdge); itempValue++; } //4. До тех пор, пока не достигнута последняя комбинация while (!lastCombination) { temp = variantValue.begin(); //Указать итератор temp на начальный элемент variantValue lastCombination = true; // Установить флаг lastCombination в истину //4.1.Сравнить переменные при текущей комбинация, //если каждая из переменных в текущей комбинации больше или равна максимальному значению из своего диапазона, //то это - последняя комбинация. for (int ii = 1; ii <= n; ii++) { //4.1.3. C помощью temp, сравнить каждый элемент у variantValue с его верхней пределом highEdge, //если у какого-либо элемента значение меньше чем highEdge, то сбросить флаг lastCombination. if (temp.value() < listVar[temp.key()].highEdge) lastCombination = false; temp++; } //4.1.4.C помощью функции calcExpression, сравнить два выражения при текущей комбинации variantValue. long long s1, s2; try { s1 = calcExpression(expr1, variantValue); s2 = calcExpression(expr2, variantValue); } catch (const QString& message) { throw (message); } //4.1.4.1. Если выражения не равны if (s1 != s2) { equivalent = false; if (variantValue.size() > 0) { //4.1.4.1.1. Создать группу с различными переменными и //их пределами lowEdge и highEdge с помощью tempValues, тип QMap<QString, DataVariable>. tempValues.clear(); temp = variantValue.begin(); for (int ii = 1; ii <= n; ii++) { tempRange.typevar = listVar[temp.key()].typevar; tempRange.lowEdge = temp.value(); tempRange.highEdge = temp.value(); tempValues.insert(temp.key(), tempRange); temp++; } //4.1.4.1.2. Добавить tempValues в выходной контейнер listRange listRange.append(tempValues); } } //4.2.Перейти к следующей комбинации if (variantValue.size() > 0) { //4.2.1. Установить temp на последнюю переменную комбинации. temp =variantValue.end(); temp--; bool stop = false; //4.2.2. Двигаться назад по массиву переменных variantValue, когда достигли предела highEdge по одному или несколько измерениям. while (temp.value() == listVar[temp.key()].highEdge&&!stop) //4.2.2.1. Если текущие значение переменной у итератора temp равно его предел highEdge. { //4.2.2.2.Присвоить данной переменной значение её нижнего предела lowEdge. temp.value() = listVar[temp.key()].lowEdge; //4.2.2.3.Перейти к предыдущей переменной(temp--) и вернуть на шаг 4.2.2.1. if (temp == variantValue.begin()) stop = true; else temp--; } //4.2.3. Если значение переменной у итератора temp меньше его верхнего предела (highEdge) //4.2.3.1.Увеличить её значение temp.value() на 1. temp.value()++; } } return equivalent; //Вернуть знак эквивалентности }
int correctHistList(void) { linelist ln; histRec * hptr; int lineNum; int i; char keyChar[2]; double rMin[2]={0.,0.}, rMax[2]={0.,0.}; char histStr[2][STRSIZ], minStr[2][STRSIZ], maxStr[2][STRSIZ]; char fieldName[50]; for( hptr = histPtr ;hptr;hptr=hptr->next) hptr->mother=NULL; for(ln=histTab.strings,lineNum=1; ln; ln=ln->next,lineNum++) { sscanf(ln->line,"%[^|]%*c%[^|]%*c%[^|]%*c%[^|]%*c%[^|]%*c%[^\n]%", histStr[0],minStr[0],maxStr[0],histStr[1],minStr[1],maxStr[1]); for(i=0;i<2;i++) { char ch; trim(minStr[i]);trim(histStr[i]);trim(maxStr[i]); /*============ Parameter ===========*/ if(strlen(histStr[i])==0) { if(i==0) { sprintf(fieldName,"Wrong field 'Parameter #%d'",i+1); goto errorExit; } else { rMin[i]=0;rMax[i]=0;} continue; } /*================ MIN bound ============*/ if(calcExpression(minStr[i],rd_num,&rMin[i] )) { sprintf(fieldName,"Wrong field 'Min. #%d bound'",i+1); goto errorExit; } /* if(1!=sscanf(minStr[i],"%lf%c",rMin+i,&ch)) { sprintf(fieldName,"Wrong field 'Min. #%d bound'",i+1); goto errorExit; } */ /*================== MAX bound ==========*/ if(calcExpression(maxStr[i],rd_num,&rMax[i] )) { sprintf(fieldName,"Wrong field 'Max. #%d bound'",i+1); goto errorExit; } /* if(1!=sscanf(maxStr[i],"%lf%c",rMax+i,&ch)) { sprintf(fieldName,"Wrong field 'Max. #%d bound'",i+1); goto errorExit; } */ } for(hptr = histPtr; hptr; hptr=hptr->next) if(hptr->mother==NULL &&strcmp(hptr->title[0],histStr[0])==0 && approxEq(hptr->hMin[0],rMin[0]) && approxEq(hptr->hMax[0],rMax[0]) &&strcmp(hptr->title[1],histStr[1])==0 && approxEq(hptr->hMin[1],rMin[1]) && approxEq(hptr->hMax[1],rMax[1]) ) { hptr->mother=ln; cleanPVlist(hptr->pList[0]); cleanPVlist(hptr->pList[1]); checkPhysValN(histStr[0],hptr->key[0],hptr->pList); if(strlen(histStr[1]))checkPhysValN(histStr[1],hptr->key[1],hptr->pList+1); else { strcpy(hptr->key[1],"0"); hptr->pList[1]=NULL;} break; } if(hptr==NULL) { physValRec *pL[2]; char key[2][4]; if(!checkPhysValN(histStr[0],key[0],pL )) { sprintf(fieldName,"Wrong field 'Parameter #1'"); goto errorExit; } if(strlen(histStr[1])) { if(!checkPhysValN(histStr[1],key[1],pL+1 )) { sprintf(fieldName,"Wrong field 'Parameter #2'"); goto errorExit; } } else {strcpy(key[1],"0") ;pL[1]=NULL;} hptr=malloc(sizeof(histRec)); hptr->next=histPtr; hptr->mother=ln; histPtr=hptr; for(i=0;i<2;i++) { strcpy(hptr->title[i], histStr[i]); strcpy(hptr->key[i],key[i]); hptr->pList[i]=pL[i]; hptr->hMin[i]=rMin[i]; hptr->hMax[i]=rMax[i]; } for(i=0;i<900;i++) {hptr->f[i]=0; hptr->ff[i]=0;} hptr->nPoints=0; } } hptr = histPtr; histPtr=NULL; while(hptr) { histRec * hptr_=hptr; hptr=hptr->next; if(!hptr_->mother) { cleanPVlist(hptr_->pList[0]); cleanPVlist(hptr_->pList[1]); free(hptr_); } else {hptr_->next=histPtr; histPtr=hptr_;} } return 0; errorExit: sprintf(errorText," Error in line %d .\n%s.",lineNum,fieldName); messanykey(2,10,errorText); return 1; }