Пример #1
0
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
														 );
}
Пример #2
0
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;  
}
Пример #3
0
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;
}
Пример #4
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);
}
Пример #5
0
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);
	}
}
Пример #6
0
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; //Вернуть знак эквивалентности

}
Пример #9
0
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;
}