Donnee* Rationnel::operator +(Donnee * t){ std::cout<<"debut opérateur"<<std::endl; if (typeid(*t)==typeid(Rationnel)){ Rationnel *tmp=static_cast<Rationnel*>(t); Rationnel *res=new Rationnel(num*tmp->denom+tmp->num*denom,denom*tmp->denom); return res; } if (typeid(*t)==typeid(Entier)){ Entier *tmp=static_cast<Entier*>(t); Rationnel cur=Rationnel(tmp); return cur+this; } if (typeid(*t)==typeid(Reel)){ Reel *tmp=static_cast<Reel*>(t); Rationnel cur=Rationnel(tmp); return cur+this; } if (typeid(*t)==typeid(Complexe)){ Complexe *tmp=static_cast<Complexe*>(t); Complexe cur(this); Donnee * res; res=cur+tmp; return res; } if (typeid(*t)==typeid(ConstanteExp)){ ConstanteExp *tmp=static_cast<ConstanteExp*>(t); QString nouv; nouv = "'" + toQString() + " "+ tmp->toQString().remove("'") + " + '"; return new ConstanteExp(nouv); } throw ExceptionCooCoo("erreur sur opérateur + avec un rationnel"); }
Constante* INV::application(const Constante& c1){ Constante* result; switch(c1.getType()){ case Constante::ENTIER: result = new Rationnel(1,static_cast<const Entier&>(c1).getEntier()); break; case Constante::RATIONNEL: result = Rationnel(1) / c1; break; case Constante::REEL: result = new Rationnel(1,(int)static_cast<const Reel&>(c1).getReel()); break; } return result; }
Expression::operator Rationnel()const { //exception return Rationnel(0, 1); }
Constante* Eval::getValue() const { Expression* exp = dynamic_cast<Expression*>(c); QStack<Constante*> p; if (exp != NULL){ int i = 0; QString s = exp->getExp(); Constante * result = 0; while(i<s.length()){ //on passe les espaces; if(s[i] == ' '){ if(result != 0){ p.push(result); result = 0; } } else if(s[i] >= '0' && s[i] <= '9'){ if(result == 0)result = Addition(Rationnel(0),Rationnel(0),mModeConstante, mModeComplexes).getValue(); result->addChiffre(s[i].toAscii() - '0'); } else if(s[i] == '$'){ if(result == 0) throw EvalException("$ mal placé"); result->setDollarEntre(); } else if(s[i] == '/'){ if(result != 0){ result->setSlashEntre(); } else{ if(p.size() < 2) throw EvalException("Pas assez d'opérandes pour /"); Constante *op2 = p.pop(), *op1 = p.pop(); try{ result = Division(*op1,*op2,mModeConstante,mModeComplexes).getValue(); } catch(DivException e){ throw EvalException("division par zéro"); } delete op1; delete op2; p.push(result); result = 0; } } else if(s[i] == ',' || s[i] == '.'){ if(result == 0) throw EvalException(", ou . mal placé"); result->setVirguleEntree(); } else if(s[i] == '+'){ if(result!=0){ p.push(result); result = 0; } if(p.size() < 2) throw EvalException("Pas assez d'opérandes pour +"); Constante *op1 = p.pop(), *op2 = p.pop(); result = Addition(*op1,*op2,mModeConstante,mModeComplexes).getValue(); delete op1; delete op2; p.push(result); result = 0; } else if(s[i] == '-'){ if(result!=0){ p.push(result); result = 0; } if(p.size() < 2) throw EvalException("Pas assez d'opérandes pour -"); Constante *op2 = p.pop(), *op1 = p.pop(); result = Soustraction(*op1,*op2,mModeConstante,mModeComplexes).getValue(); delete op1; delete op2; p.push(result); result = 0; } else if(s[i] == '*'){ if(result!=0){ p.push(result); result = 0; } if(p.size() < 2) throw EvalException("Pas assez d'opérandes pour *"); Constante *op2 = p.pop(), *op1 = p.pop(); result = Multiplication(*op1,*op2,mModeConstante,mModeComplexes).getValue(); delete op1; delete op2; p.push(result); result = 0; } else{ throw EvalException("Caractère inconnu"); } i++; } if(result!=0)p.push(result); if(p.size() > 1) throw EvalException("Il manque un opérateur."); if(p.size() < 1) throw EvalException("Pile d'évaluation vide."); return p.at(0); } else throw TypeConstanteException("Ceci n'est pas une expression"); }
void OperateurBinaire::Calculer(Pile* stack){ Donnee* dB= stack->depiler(); // On commence par depiler les 2 dernieres donnees entrees. B est la derniere donne empile, donc le second membre de l'operation. La seconde donne empile est le premier membre, A. Donnee* dA= stack->depiler(); Expression* testExA =dynamic_cast<Expression*>(dA); // On verifie d'abord si l'une des 2 donnees n'est pas une expression. Il faudra alors cancatener l'expression avec l'autre donnee et l'operateur. Expression* testExB =dynamic_cast<Expression*>(dB); if (testExA) { testExA->enfiler_fin(dB); testExA->enfiler_fin(this); // Si le premier membre est une expression, il faut enfiler le second membre et l'operateur à la fin successivement. stack->empiler(testExA); } else if (testExB) { testExB->enfiler_debut(dA); testExB->enfiler_fin(this); // Si le second membre est une expression et que le premier ne l'est pas, il faut enfiler le premier membre au début de B, et l'operateur à la fin. stack->empiler(testExB); } else { Complexe* testC1 = dynamic_cast< Complexe*>(dA); Complexe* testC2 = dynamic_cast< Complexe*>(dB); Reel* test1 = dynamic_cast< Reel*>(dA); Reel* test2 = dynamic_cast< Reel*>(dB); Rationnel* test3 = dynamic_cast< Rationnel*>(dA); Rationnel* test4 = dynamic_cast< Rationnel*>(dB); Entier* testE1 = dynamic_cast< Entier*>(dA); Entier* testE2 = dynamic_cast< Entier*>(dB); if ( testC1 || testC2){ //On a au moins un complexe. On travaille donc avec des complexes. Complexe A= Complexe(dA); // constructeur de complexe a partir de donnee. Complexe B= Complexe(dB); switch (typeoperation) { // Switch selon le type de l'operation, attribut de l'operateurBinaire. case (PLUS): { Complexe *X= new Complexe(A+B); stack->empiler(X); } break; case(MINUS): { Complexe *X= new Complexe(A-B); stack->empiler(X); } break; case(DIV): { if (B.CNull()){ // Cas ou une division par zero est tentée. stack->empiler(dA); stack->empiler(dB); throw CalculException("Division par zero impossible."); } else { Complexe *X= new Complexe(A/B); stack->empiler(X); } } break; case (MULT): { Complexe *X= new Complexe(A*B); stack->empiler(X); } break; case(MODULO): { stack->empiler(dA); // Modulo inappliquable sur complexes. On re-empile donc les donnees dans le bon ordre. stack->empiler(dB); throw CalculException("Modulo inappliquable pour Complexe.\nFonction utilisable avec Entier uniquement."); } break; case (POW): { stack->empiler(dA); stack->empiler(dB); throw CalculException("POW inappliquable pour Complexe."); } break; } } else if ( test1 || test2 ) { //Au moins un reel Reel A=Reel(dA); Reel B=Reel(dB); Reel* dC = new Reel; switch (typeoperation) { case (PLUS): { *dC=(A+B); stack->empiler(dC); } break; case(MINUS): { *dC=(A-B); stack->empiler(dC); } break; case(DIV): { if (B.getVal()==0){ //Cas ou une division par zero est tentée. stack->empiler(dA); stack->empiler(dB); throw CalculException("Division par zero impossible."); } else { *dC=(A/B); stack->empiler(dC); } } break; case (MULT): { *dC=(A*B); stack->empiler(dC); } break; case(MODULO): { stack->empiler(dA); stack->empiler(dB); throw CalculException("Modulo inappliquable pour Reel.\nFonction utilisable avec Entier uniquement."); } break; case (POW): { *dC=(A*B); *dC=Reel(pow(A.getVal(),B.getVal())); stack->empiler(dC); } break; } } else if ( test3 || test4 ) { //Au moins un rationnel Rationnel A=Rationnel(dA); Rationnel B=Rationnel(dB); Rationnel* dC = new Rationnel; switch (typeoperation) { case (PLUS): { *dC=(A+B); stack->empiler(dC); } break; case(MINUS): { *dC=(A-B); stack->empiler(dC); } break; case(DIV): { if (B.getNumerateur().getVal()==0){ stack->empiler(dA); stack->empiler(dB); throw CalculException("Division par zero impossible."); } else { *dC=(A/B); stack->empiler(dC); } } break; case (MULT): { *dC=(A*B); stack->empiler(dC); } break; case(MODULO): { stack->empiler(dA); stack->empiler(dB); throw CalculException("Modulo inappliquable pour Rationnel.\nFonction utilisable avec Entier uniquement."); } break; case (POW): { *dC=Rationnel(pow(A.getNumerateur(),float(B)),pow(A.getDenumerateur(),float(B))); stack->empiler(dC); } break; } } else if ( testE1 || testE2){ //On a forcément deux entiers Entier* C = new Entier; // Il est inutile de creer des variables locales entieres et de proceder a une conversion a partir de donnee, puisque testE1 et testE2 sont tout les 2 forcéments des entiers. Nous pouvons donc les utiliser dans le calcul. switch (typeoperation) { case (PLUS): { *C = *testE1 + *testE2; stack->empiler(C); } break; case(MINUS): { *C = *testE1 - *testE2; stack->empiler(C); } break; case(DIV): { if (testE2->getVal()==0){ stack->empiler(testE1); stack->empiler(testE2); throw CalculException("Division par zero impossible."); } else { *C = *testE1 / *testE2; stack->empiler(C); } } break; case (MULT): { *C = *testE1 * *testE2; stack->empiler(C); } break; case(MODULO): { if (testE2->getVal()==0){ stack->empiler(testE1); stack->empiler(testE2); throw CalculException("Modulo: Division par zero impossible."); } else { *C = *testE1 % *testE2; stack->empiler(C); } } break; case (POW): { *C = Entier(pow(testE1->getVal(),testE2->getVal())); stack->empiler(C); } break; } } else throw CalculException("Echec de la reconnaissance du type de 2 variables entrees.\nSource: Operateurbinaire.cpp. "); } }
Rationnel::operator Complexe()const { return Complexe(&Rationnel(num, den), &Entier(0)); }