void CommandeSqr::execute()throw(LogMessage){ savePileAvtExe(); Constante * c; try{ c =_pileCourante->depiler(); if(typeid(*c)!=typeid(Complexe) && typeid(*c)!=typeid(Expression)){ //clone la constante pour pas la modifier et empiler la rempiler la mauvaise version s'il y a un problème Constante* clone = c->clone(); Nombre * nbClone = dynamic_cast<Nombre*>(clone); nbClone->sqr_(); if(empilerNombre(nbClone)) savePileApresExe(); else _pileCourante->empilerConstante(c); } else if(typeid(*c)==typeid(Complexe)){ Constante* clone = c->clone(); Complexe* coClone = dynamic_cast<Complexe*>(clone); coClone->sqr(); if(empilerComplexe(coClone)) savePileApresExe(); else _pileCourante->empilerConstante(c); } else{ _pileCourante->empilerConstante(c); throw LogMessage("Impossible de faire un carré sur une Expression, Il faut d'abord l'évaluer",1); } } catch(LogMessage &msg){ throw; } }
Element* Calculateur::inv() { if(typeid(*this->pileC->top()) == typeid(Expression)) { throw std::logic_error("L'élément du haut de la pile est une expression"); } if(typeid(*this->pileC->top()) == typeid(Complexe)) { throw std::logic_error("L'inverse d'un complexe n'est pas une commande disponible"); } Constante* c = dynamic_cast<Constante *>(this->pileC->pop()); Element* res; if(typeid(*c)== typeid(Entier) || typeid(*c)== typeid(Rationnel)) { res = new Rationnel(c->getYAsInt(),c->getXAsInt()); } else { res = new Reel(1./c->getXAsFloat()); } delete c; this->pileC->push(res); return res; }
Constante* Pile::dupliquer() { Constante* temp = p.top(); string s = temp->getChaine(); if(temp == NULL) return NULL; if(temp->getType() == entier) { Entier* Dup = new Entier(s); return Dup; } else if(temp->getType() == rationnel) { Rationnel* Dup = new Rationnel(s); return Dup; } else if(temp->getType() == reel) { Reel* Dup = new Reel(s); return Dup; } else { Complexe* temp2 = dynamic_cast<Complexe*>(temp); Complexe* Dup = new Complexe(s, temp2->getContient()); return Dup; } }
void CalculatriceModele::getMean(int type){ if(pile.size()>=1){ Constante* a = pile.pop(); if(typeid (*a).name()==typeid (Entier).name()){ Entier* e = dynamic_cast<Entier*>(a); if(pile.size()>=e->GetEntier()) { Rationnel nb_moyenne = e->inv(); pile.push(e); emit getSum(type); a = pile.pop(); Constante* res = nb_moyenne * a; qDebug()<<"res :"<<res->ConvertChaine(); pile.push(res); } else{ pile.push(a); logger1->Write(&LogMessage(ERROR,"taille pile insuffisante")); logger2->Write(&LogMessage(ERROR,"taille pile insuffisante")); } } else{ logger1->Write(&LogMessage(ERROR,"type non conforme")); logger2->Write(&LogMessage(ERROR,"type non conforme")); } emit finOp(&pile); } else{ logger1->Write(&LogMessage(ERROR,"taille pile insuffisante")); logger2->Write(&LogMessage(ERROR,"taille pile insuffisante")); } }
bool Inferieur::application(const Constante& c1, const Constante& c2){ bool result; if(c1.getType() > c2.getType()){ result = c1<c2; } else{ result = c2<c1; } return result; }
bool Egal::application(const Constante& c1, const Constante& c2){ bool result; if(c1.getType() > c2.getType()){ result = c1==c2; } else{ result = c2==c1; } return result; }
void Pile::afficher(int tailleMax){ QString txt = ""; int j = 0; for ( int i = size() - 1; i >=0; i-- ) { j++; if(j>tailleMax) break; Constante * c = at(i); txt+=c->getValuetoString(); if(i<size()) txt+= " | "; } affichage->setText("Pile : |" + txt); }
Element* Calculateur::log() { if(typeid(*this->pileC->top()) == typeid(Expression)) { this->eval(); } if(typeid(*this->pileC->top()) == typeid(Complexe)) { // } if(isRadian()) { Constante* tmp = dynamic_cast<Constante*> (this->pileC->pop()); if(tmp->getXAsFloat()<0 && tmp->getYAsFloat() <0) { //ERREUR return 0; } else { Reel* resu = new Reel(::log10(tmp->getXAsFloat()/tmp->getYAsFloat())); delete tmp; this->pileC->push(resu); return resu; } } else { Constante* tmp = dynamic_cast<Constante*> (this->pileC->pop()); if(tmp->getXAsFloat()<0 && tmp->getYAsFloat() <0) { //ERREUR return 0; } else { Reel* resu = new Reel(::log10((tmp->getXAsFloat()/tmp->getYAsFloat()))); delete tmp; this->pileC->push(resu); return resu; } } }
Element* Calculateur::tanh() { if(typeid(*this->pileC->top()) == typeid(Expression)) { this->eval(); } if(typeid(*this->pileC->top()) == typeid(Complexe)) { // } if(isRadian()) { Constante* tmp = dynamic_cast<Constante*> (this->pileC->pop()); Reel* resu = new Reel(::tanh(tmp->getXAsFloat()/tmp->getYAsFloat())); delete tmp; this->pileC->push(resu); return resu; } else { Constante* tmp = dynamic_cast<Constante*> (this->pileC->pop()); Reel* resu = new Reel(::tanh((tmp->getXAsFloat()/tmp->getYAsFloat())*PI/180.0)); delete tmp; this->pileC->push(resu); return resu; } }
void main() { Contexto contexto; // Declaracion de Variables Variable *x = new Variable("x"); Variable *y = new Variable("y"); // Asignacion de variables contexto.asignar(x, 8); contexto.asignar(y, 4); // Declaracion de constantes Constante *constante = new Constante(2); // Operacion compuesta (constante * x) + (y / constante) E *operacion = new Suma(new Multiplica(constante, x), new Divide(y, constante)); // Operaciones de E E *eSuma = new Suma(x, y); E *eResta = new Resta(x, y); // Operaciones de T T *tMultiplica = new Multiplica(x, y); T *tDivide = new Divide(x, y); cout<< "Valor Variable x = " << contexto.getValor("x") << endl; cout<< "Valor Variable y = " << contexto.getValor("y") << endl; cout<< "Valor Constante = " << constante->getValor(contexto) << endl; cout<< endl; cout<< "Suma: " << eSuma->getValor(contexto) << endl; cout<< "Resta: " << eResta->getValor(contexto) << endl; cout<< "Multiplicacion: " << tMultiplica->getValor(contexto) << endl; cout<< "Division: " << tDivide->getValor(contexto) << endl; cout<< "Operacion compuesta: " << operacion->getValor(contexto) << endl; delete x; delete y; }
void CommandeLn::execute()throw(LogMessage){ savePileAvtExe(); Constante * c; try{ c=_pileCourante->depiler(); if(typeid(*c)!=typeid(Complexe) && typeid(*c)!=typeid(Expression)){ //clone la constante pour pas la modifier et empiler la rempiler la mauvaise version s'il y a un problème Constante* clone = c->clone(); Nombre * n = dynamic_cast<Nombre*>(clone); n->ln_(); if(empilerNombre(n)) savePileApresExe(); else _pileCourante->empilerConstante(c); } else{ _pileCourante->empilerConstante(c); throw LogMessage("Impossible de faire un logarithme neperien sur un Complexe ou une Expression",1); } } catch(LogMessage &msg){ throw; } }
/*! * bool operator<(const Constante& c) const * \brief operator< * Methode vérifiant si l'entier manipulé est inférieur à la constante passé en argument * Si la constante est un entier, alors on effectue l'operation adequate * \param c * \return true si l'entier manipulé est inférieur, false sinon */ bool Entier::operator<(const Constante & c) const { switch(c.getType()){ case Constante::ENTIER: { if(this->_entier < static_cast<const Entier&>(c)._entier) { return true; } else { return false; } } } }
Element* Calculateur::pow() { if(typeid(*this->pileC->top()) == typeid(Expression)) { this->eval(); } if(typeid(*this->pileC->top()) == typeid(Complexe)) { throw std::logic_error("Le premier élément ne peut pas être un complexe"); } else if(typeid(*this->pileC->top())== typeid(Entier)) { Entier* e = dynamic_cast<Entier*>(this->pileC->pop()); if(typeid(*this->pileC->top()) == typeid(Expression)) { Element* tmp = this->eval(); } else if(typeid(*this->pileC->top())== typeid(Entier) || typeid(*this->pileC->top())== typeid(Rationnel)) { Constante* c = dynamic_cast<Constante*>(this->pileC->pop()); if(e->getXAsInt()>= 0) { Rationnel* tmp = new Rationnel(::pow(c->getXAsInt(),e->getXAsInt()),::pow(c->getYAsInt(),e->getXAsInt())); qDebug()<<tmp->toQString(); Element* res = this->cast(tmp); delete e; delete c; delete tmp; this->pileC->push(res); } else { Reel* tmp = new Reel(::pow(c->getXAsFloat()/c->getYAsFloat(),e->getXAsInt())); Element* res = this->cast(tmp); delete e; delete c; delete tmp; this->pileC->push(res); } } else if(typeid(*this->pileC->top()) == typeid(Reel)) { Constante* c = dynamic_cast<Constante*>(this->pileC->pop()); Reel* tmp = new Reel(::pow(c->getXAsFloat(),e->getXAsFloat())); Element* res = this->cast(tmp); delete e; delete c; delete tmp; this->pileC->push(res); } else { throw std::logic_error("L'élément n'est pas un type connu"); } } else if(typeid(*this->pileC->top()) == typeid(Reel) || typeid(*this->pileC->top()) == typeid(Rationnel)) { Constante* p = dynamic_cast<Constante*>(this->pileC->pop()); if((typeid(*this->pileC->top()) == typeid(Entier))||(typeid(*this->pileC->top()) == typeid(Rationnel)) || typeid(*this->pileC->top()) == typeid(Reel)) { Constante* c = dynamic_cast<Constante*>(this->pileC->pop()); Reel* tmp = new Reel(::pow(c->getXAsFloat()/c->getYAsFloat(),p->getXAsFloat()/p->getYAsFloat())); Element* res = this->cast(tmp); delete p; delete c; delete tmp; this->pileC->push(res); return res; } else { throw std::logic_error("Le deuxième élément n'est pas un type valide"); } } else { throw std::logic_error("Le premier élément n'est pas un élément valide"); } }
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 OperateurPile::Execution() { if (operation=="SWAP") { Constante * c1; Constante * c2; c1=Historique::GetInstance()->GetPileCalcul().Depiler(); c2=Historique::GetInstance()->GetPileCalcul().Depiler(); this->SWAP(c1, c2); QString opG=c1->ToQString(); QString opD=c2->ToQString(); LogSystem::GetInstance()->Publier(LogMessage("Echange de l'élément "+opG+" avec "+opD,2)); delete c1; delete c2; } if (operation=="SUM") { Constante * c1=Historique::GetInstance()->GetPileCalcul().Depiler(); Historique::GetInstance()->GetPileCalcul().Empiler(this->SUM(c1)); QString opG=c1->ToQString(); LogSystem::GetInstance()->Publier(LogMessage("Somme des "+opG+" premiers éléments",2)); delete c1; } if (operation=="MEAN") { Entier * c1 = dynamic_cast<Entier *>(Historique::GetInstance()->GetPileCalcul().Depiler()); if (c1==NULL) { throw Exception("Erreur : Impossible de faire la moyenne d'un nombre non entier d'éléments."); } else { Constante * temp = this->SUM(c1); Historique::GetInstance()->GetPileCalcul().Empiler(temp->operator/(c1)); delete temp; QString opG=c1->ToQString(); LogSystem::GetInstance()->Publier(LogMessage("Moyenne des"+opG+" premiers éléments",2)); delete c1; } } if (operation=="CLEAR") { /* Il faut penser à liberer la memoire quand on vide la pile*/ PileCalcul& p=Historique::GetInstance()->GetPileCalcul(); p.Vider(); LogSystem::GetInstance()->Publier(LogMessage("La pile est vidée",2)); } if (operation=="DUP") { Constante * temp = Historique::GetInstance()->GetPileCalcul().Depiler(); Constante * cpy = temp->clone(); Constante * cpy2 = temp->clone(); delete temp; Historique::GetInstance()->GetPileCalcul().Empiler(cpy2); Historique::GetInstance()->GetPileCalcul().Empiler(cpy); LogSystem::GetInstance()->Publier(LogMessage("Dédoublement du premier élément de la Pile",2)); } if (operation=="DROP") { delete Historique::GetInstance()->GetPileCalcul().Depiler(); LogSystem::GetInstance()->Publier(LogMessage("Le premier élément de la pile a été effacé",2)); } }
// fabrique soit une constante soit un opérateur (et l'éxécute). void Calculatrice::fabriquer(const QString& text, enumType type) const { Pile* p = &Pile::getInstance(); PileAffichage* pA = &PileAffichage::getInstance(); switch (type) { case ENTIER:{ Constante* res = new Entier(text.toInt()); p->push(res); // ajout log dans le fichier de log LogSystem::add("Push dans la pile : " + res->toString(),FAIBLE); // on push dans la pile d'affichage pA->push(text); break; } case REEL:{ Constante* res = new Reel(text.toDouble()); p->push(res); // ajout log dans le fichier de log LogSystem::add("Push dans la pile : " + res->toString(),FAIBLE); // on push dans la pile d'affichage pA->push(text); break; } case RATIONNEL:{ // séparation num / den QStringList tmp = text.split("/"); Constante* res = new Rationnel(tmp.value(0).toInt(), tmp.value(1).toInt()); p->push(res); // ajout log dans le fichier de log LogSystem::add("Push dans la pile : " + res->toString(),FAIBLE); // on push dans la pile d'affichage pA->push(text); break; } case COMPLEXE:{ // séparation re $ im QStringList tmp = text.split("$"); // push la partie réelle du complexe if (this->isEntier(tmp.value(0))) { this->fabriquer(tmp.value(0),ENTIER); } else if (this->isReel(tmp.value(0))) { this->fabriquer(tmp.value(0),REEL); } else if (this->isRationnel(tmp.value(0))) { this->fabriquer(tmp.value(0),RATIONNEL); } // push la partie imaginaire du complexe if (this->isEntier(tmp.value(1))) { this->fabriquer(tmp.value(1),ENTIER); } else if (this->isReel(tmp.value(1))) { this->fabriquer(tmp.value(1),REEL); } else if (this->isRationnel(tmp.value(1))) { this->fabriquer(tmp.value(1),RATIONNEL); } // pop les deux parties const NonComplexe* c1 = dynamic_cast<const NonComplexe*>(p->pop()); const NonComplexe* c2 = dynamic_cast<const NonComplexe*>(p->pop()); // construction du complexe et push. Complexe* res = new Complexe(*c2, *c1); p->push(res); // ajout log dans le fichier de log LogSystem::add("Push dans la pile : " + res->toString(),FAIBLE); // on push dans la pile d'affichage pA->push(text); break; } case OPERATEUR:{ Operateur* res = new Operateur(text); // ajout log dans le fichier de log LogSystem::add("Traitement opération : " + text,FAIBLE); // on push dans la pile d'affichage pA->push(text); res->effectuerOperation(); break; } case EXPRESSION:{ QString tmp(text); tmp.replace(QString("'"), QString("")); Constante* res = new Expression(tmp); p->push(res); // ajout log dans le fichier de log LogSystem::add("Push dans la pile : " + res->toString(),FAIBLE); // on push dans la pile d'affichage pA->push(text); break; } default:{ QMessageBox::critical(0,"Erreur !", "Fabrication d'objet impossible!"); // ajout log dans le fichier de log LogSystem::add("Fabrication d'objet impossible",ELEVEE); break; } } }