Nombre& Entier::soustraction(const Nombre& n) const { // Nombre -> Entier const Entier* ptEntier = dynamic_cast<const Entier*>(&n); if (ptEntier == 0) { // Nombre -> Reel const Reel* ptReel = dynamic_cast<const Reel*>(&n); if (ptReel == 0) { // Nombre -> Rationnel const Rationnel* ptRationnel = dynamic_cast<const Rationnel*>(&n); if (ptRationnel == 0) { throw CalculatriceException("Entier : soustraction : Impossible d'effectuer le dynamic cast!"); } else { // Entier - Rationnel Entier num(mX * ptRationnel->getDen().getX() - ptRationnel->getNum().getX()); Entier den(ptRationnel->getDen().getX()); Rationnel* res = new Rationnel(num.toEntier(), den.toEntier()); res->simplifier(); Nombre& ref = *res; return(ref); } } else { // Entier - Reel Reel* res = new Reel(mX - ptReel->getX()); Nombre& ref = *res; return(ref); } } else { // Entier - Entier Entier* res = new Entier(mX - ptEntier->getX()); Nombre& ref = *res; return(ref); } }
Reel::Reel(Rationnel r){ float Num=(float)r.getNumerateur().getVal(); // Redondant le (float) ? float Denum=(float)r.getDenumerateur().getVal(); val=Num/Denum; }
void Complexe::buildConstant(const std::string& val) { int i = val.find_first_of('$'); string temp1 = val.substr(0, i); string temp2 = val.substr(i+1); if(complexe_type_contenu == entier) { _reel = new Entier(temp1); _img = new Entier(temp2); } else if(complexe_type_contenu == rationnel) { Rationnel* n = new Rationnel(temp1); n->simplifier(); _reel = n; Rationnel* n2 = new Rationnel(temp2); n2->simplifier(); _img = n2; } else if(complexe_type_contenu == reel) { _reel = new Reel(temp1); _img = new Reel(temp2); } }
Complexe::Complexe(const QString& pRe, const QString& pIm){ if(typeLitteral(pRe)=="Entier") a = new Entier(pRe); else if(typeLitteral(pRe)=="Reel") a = new Reel(pRe); else if(typeLitteral(pRe)=="Rationnel"){ Rationnel* rat = new Rationnel(pRe); rat->simplifier(); if(rat->getDenumerateur()->getVal() == 1 || rat->getNumerateur()->getVal() ==0){ Entier* e = new Entier(rat->getNumerateur()->getVal()); a = e; } else{ a = rat; } } if(typeLitteral(pIm)=="Entier") b = new Entier(pIm); else if(typeLitteral(pIm)=="Reel") b = new Reel(pIm); else if(typeLitteral(pIm)=="Rationnel"){ Rationnel* rat = new Rationnel(pIm); rat->simplifier(); if(rat->getDenumerateur()->getVal() == 1 || rat->getNumerateur()->getVal() ==0){ Entier* e = new Entier(rat->getNumerateur()->getVal()); b = e; } else{ b = rat; } } }
/*! \sa Compexe */ Rationnel::operator Complexe()const { Rationnel* r = new Rationnel(num, den); r->simplifier(); Rationnel* zero = new Rationnel(0, 1); return Complexe(r, zero); }
Rationnel Entier::puissance (Entier r1){ Rationnel res; int res_i=1; for(int i=0; i<r1.n; i++){res_i = res_i * n;} if (r1.n < 0) {res.SetDen(res_i);} else if(r1.n == 0){res.SetNum(1);} else{res.SetNum(res_i);} res.Simplification(); return res; }
Element& Reel::operator/(Element& e) { if(typeid(e) == typeid(Complexe)) { Complexe& ecast = dynamic_cast<Complexe &>(e); if(typeid(*ecast.getRe()) == typeid(Entier)) { Entier* ccast = dynamic_cast<Entier *>(ecast.getRe()); Reel* tmp = new Reel(this->getX() / (float)ccast->getX()); return *(new Complexe(tmp, ecast.getIm()->clone())); } else if(typeid(*ecast.getRe()) == typeid(Reel)) { Reel* rcast = dynamic_cast<Reel *>(ecast.getRe()); Reel* tmp = new Reel(this->getX() / rcast->getX()); return *(new Complexe(tmp, ecast.getIm()->clone())); } else if(typeid(*ecast.getRe()) == typeid(Rationnel)) { Rationnel* rcast = dynamic_cast<Rationnel *>(ecast.getRe()); Reel* tmp = new Reel(this->getX()/((float)rcast->getX()/(float)rcast->getY())); return *(new Complexe(tmp, ecast.getIm()->clone())); } } else if(typeid(e) == typeid(Entier)) { Entier& ecast = dynamic_cast<Entier &>(e); return *(new Reel(this->getX() / (float)ecast.getX())); } else if(typeid(e) == typeid(Expression)) { Expression& ecast = dynamic_cast<Expression &>(e); return *(new Expression(this->toQString() + ' ' + ecast.getX() + ' / ')); } else if(typeid(e) == typeid(Rationnel)) { Rationnel& rcast = dynamic_cast<Rationnel &>(e); return *(new Reel(this->getX()/((float)rcast.getX()/(float)rcast.getY()))); } else if(typeid(e) == typeid(Reel)) { Reel& rcast = dynamic_cast<Reel &>(e); return *(new Reel(this->getX() / rcast.getX())); } else{qDebug()<<"erreur";} }
Element& Reel::operator+(Element& e) { if(typeid(e) == typeid(Complexe)) //! Si l'element en argument est un complexe { Complexe& ecast = dynamic_cast<Complexe &>(e); if(typeid(*ecast.getRe()) == typeid(Entier*)) { Entier* ccast = dynamic_cast<Entier *>(ecast.getRe()); Reel* tmp = new Reel(ccast->getX()+ this->getXAsFloat()); return *(new Complexe(tmp, ecast.getIm()->clone())); } else if(typeid(*ecast.getRe()) == typeid(Reel)) { Reel* rcast = dynamic_cast<Reel *>(ecast.getRe()); Reel* tmp = new Reel(rcast->getX() + this->getX()); return *(new Complexe(tmp, ecast.getIm()->clone())); } else if(typeid(*ecast.getRe()) == typeid(Rationnel)) { Rationnel* rcast = dynamic_cast<Rationnel *>(ecast.getRe()); Reel* tmp = new Reel(((float)rcast->getX()/(float)rcast->getY()) + this->getX()); return *(new Complexe(tmp, ecast.getIm()->clone())); } } else if(typeid(e) == typeid(Entier)) { Entier& ecast = dynamic_cast<Entier &>(e); return *(new Reel((float)ecast.getX()+this->getX())); } else if(typeid(e) == typeid(Expression)) { Expression& ecast = dynamic_cast<Expression &>(e); return *(new Expression( this->toQString() + ' ' + ecast.getX() + ' + ')); } else if(typeid(e) == typeid(Rationnel))//! Si l'element en argument est un rationnel { Rationnel& rcast = dynamic_cast<Rationnel &>(e); return *(new Reel(((float)rcast.getX()/(float)rcast.getY())+this->getX())); } else if(typeid(e) == typeid(Reel)) //! Si l'element en argument est un reel { Reel& rcast = dynamic_cast<Reel &>(e); return *(new Reel(rcast.getX()+this->getX())); } }
Element& Entier::operator-(Element& e) { if(typeid(e) == typeid(Complexe)) { Complexe& ecast = dynamic_cast<Complexe &>(e); if(typeid(ecast.getRe()) == typeid(Entier*)) { Entier* ccast = dynamic_cast<Entier *>(ecast.getRe()); Entier* tmp = new Entier(this->getX() - ccast->getX()); return *(new Complexe(tmp, ecast.getIm()->clone())); } else if(typeid(ecast.getRe()) == typeid(Reel*)) { Reel* rcast = dynamic_cast<Reel *>(ecast.getRe()); Reel* tmp = new Reel((float) this->getX() - rcast->getX()); return *(new Complexe(tmp, ecast.getIm()->clone())); } else if(typeid(ecast.getRe()) == typeid(Rationnel*)) { Rationnel* rcast = dynamic_cast<Rationnel *>(ecast.getRe()); Rationnel* tmp = new Rationnel(this->getX()*rcast->getY() - rcast->getX(), rcast->getY()); return *(new Complexe(tmp, ecast.getIm()->clone())); } } else if(typeid(e) == typeid(Entier)) { Entier& ecast = dynamic_cast<Entier &>(e); return *(new Entier(this->getX() - ecast.getX())); } else if(typeid(e) == typeid(Expression)) { Expression& ecast = dynamic_cast<Expression &>(e); return *(new Expression( this->toQString() + ' ' + ecast.getX() + ' - ')); } else if(typeid(e) == typeid(Rationnel)) { Rationnel& rcast = dynamic_cast<Rationnel &>(e); return *(new Rationnel(this->getX()*rcast.getY() - rcast.getX(), rcast.getY())); } else if(typeid(e) == typeid(Reel)) { Reel& rcast = dynamic_cast<Reel &>(e); return *(new Reel((float)this->getX() - rcast.getX())); } }
/*! On verifie que le numerateur de l'argument implicite soit differente de 0. \return Une reference sur une Constante contenant notre nouveau Rationnel. \sa CalcException */ Constante& Rationnel::inverse()const { try { if(num!=0) { Rationnel* res = new Rationnel(den, num); res->simplifier(); return *res; } else throw CalcException("L'opération d'inverse est impossible avec zéro"); } catch (CalcException c) { c.alert(); } }
/*! \param c Une reference constante vers une Constante. \return Une reference sur une Constante contenant notre nouveau Rationnel. \sa CalcException \sa <a href="http://www.cplusplus.com/reference/clibrary/cmath/pow/">pow</a> */ Constante& Rationnel::operator^(const Constante& c)const { try { const Rationnel* r = dynamic_cast<const Rationnel*>(&c); if(r!=0) { Rationnel* res = new Rationnel((int)pow((float)num, (float)(r->GetNum()/r->GetDen())), (int)pow((float)den, (float)(r->GetNum()/r->GetDen()))); res->simplifier(); return *res; } else throw CalcException("L'opération d'elevation à l'exposant nécessite que les deux opérandes soient de même type"); } catch (CalcException c) { c.alert(); } }
/*! A noter que l'on tente un dynamic cast sur l'argument qui est la seulement en cas d'un developpement futur car toutes nos operandes sont castees avant d'effectuer n'importe quelle operation. \param c Une reference constante vers une Constante. \return Une reference sur une Constante contenant notre nouveau Rationnel. \sa CalcException */ Constante& Rationnel::operator+(const Constante& c)const//ADAPTER A FAIRE { try { const Rationnel* r = dynamic_cast<const Rationnel*>(&c); if(r!=0) { Rationnel* res = new Rationnel(num*r->GetDen() + r->GetNum()*den, den*r->GetDen()); res->simplifier(); return *res; } else { throw CalcException("L'opération d'addition nécessite que les deux opérateurs soient de même type"); } } catch (CalcException c) { c.alert(); } }
Reel Entier::puissance (Rationnel r1){return pow(this->GetReel(), r1.GetRationnel());}
Rationnel Entier::operator / (Rationnel r1){ Rationnel res(n*r1.GetDen(), r1.GetNum()); res.Simplification(); return res; }
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"); } }
Rationnel::Rationnel (const Rationnel & a) { genre = a.genre; numerateur = new Entier(a.getNum()->getChain()); denominateur = new Entier(a.getDen()->getChain()); }
void CommandeDivision::execute()throw(LogMessage){ savePileAvtExe(); Constante* c1; Constante* c2; try{ c1 = _pileCourante->depiler(); c2 = _pileCourante->depiler(); if(typeid(*c1)==typeid(Expression) && typeid(*c2)==typeid(Expression)){ throw LogMessage("addition(): impossible d'appliquer un operateur sur 2 expressions",1); } if (typeid(*c1)==typeid(Expression)){ Expression* oldExpr=dynamic_cast<Expression*>(c1); QString oldChaine=oldExpr->getExp(); QString newChaine; if(typeid(*c2)!=typeid(Complexe)){ Nombre* nb=dynamic_cast<Nombre*>(c2); newChaine = nb->toQString(); } else{ Complexe* nb=dynamic_cast<Complexe*>(c2); newChaine = nb->toQString(); } oldChaine.remove(oldChaine.length()-1,1); _pileCourante->empilerExpression(oldChaine.append(" "+newChaine+" "+'/'+'\'')); } else if (typeid(*c2)==typeid(Expression)){ Expression* oldExpr=dynamic_cast<Expression*>(c2); QString oldChaine=oldExpr->getExp(); QString newChaine; if(typeid(*c1)!=typeid(Complexe)){ Nombre* nb=dynamic_cast<Nombre*>(c1); newChaine = nb->toQString(); } else{ Complexe* nb=dynamic_cast<Complexe*>(c1); newChaine = nb->toQString(); } oldChaine.remove(oldChaine.length()-1,1); _pileCourante->empilerExpression(oldChaine.append(" "+newChaine+" "+'/'+'\'')); } else{ if(_utilisateur->useComplexe()){ Complexe *co1; Complexe *co2; if(typeid(*c1)==typeid(Complexe)) co1 =dynamic_cast<Complexe*>(c1); else if(typeid(*c1)==typeid(Entier)){ Entier* nb = dynamic_cast<Entier*>(c1); co1 = nb->toComplexe(); } else if(typeid(*c1)==typeid(Rationnel)){ Rationnel* nb = dynamic_cast<Rationnel*>(c1); co1 = nb->toComplexe(); } else if(typeid(*c1)==typeid(Reel)){ Reel* nb = dynamic_cast<Reel*>(c1); co1 = nb->toComplexe(); } if(typeid(*c2)==typeid(Complexe)) co2 = dynamic_cast<Complexe*>(c2); else if(typeid(*c2)==typeid(Entier)){ Entier* nb = dynamic_cast<Entier*>(c2); co2 = nb->toComplexe(); } else if(typeid(*c2)==typeid(Rationnel)){ Rationnel* nb = dynamic_cast<Rationnel*>(c2); co2 = nb->toComplexe(); } else if(typeid(*c2)==typeid(Reel)){ Reel* nb = dynamic_cast<Reel*>(c2); co2 = nb->toComplexe(); } if(_utilisateur->useEntier()){ co1->attrToEntier(); co2->attrToEntier(); } else if(_utilisateur->useRationnel()){ co1->attrToRationnel(); co2->attrToRationnel(); } else if(_utilisateur->useReel()){ co1->attrToReel(); co2->attrToReel(); } if(co1->getReel()==0 && co2->getImg()==0) throw LogMessage("division(): impossible de diviser par 0",1); else{ Complexe * res = *(co1)/co2; _pileCourante->empilerConstante(res); savePileApresExe(); } } else{ if(typeid(*c1)==typeid(Complexe) || typeid(*c2)==typeid(Complexe)) throw LogMessage("division(): impossible de convertir un complexe en un autre type de constante, cochez complexe",1); if(_utilisateur->useEntier()){ Entier *e1; Entier *e2; int choix=QMessageBox::Ok; if(typeid(*c1)!=typeid(Expression)&& typeid(*c2)!=typeid(Expression)){ if(typeid(*c1)==typeid(Reel) || typeid(*c1)==typeid(Rationnel) || typeid(*c2)==typeid(Reel) || typeid(*c2)==typeid(Rationnel)){ choix=continuer(); } if(choix==QMessageBox::Ok){ Nombre * n1 = dynamic_cast<Nombre*>(c1); e1 = n1->toEntier(); Nombre * n2 = dynamic_cast<Nombre*>(c2); e2 = n2->toEntier(); if (e2->getNb()==0) throw LogMessage("division(): impossible de diviser par 0",1); else{ Entier * res = *(e1)/e2; _pileCourante->empilerConstante(res); savePileApresExe(); } } else{ _pileCourante->empilerConstante(c2); _pileCourante->empilerConstante(c1); } } else{ _pileCourante->empilerConstante(c2); _pileCourante->empilerConstante(c1); throw LogMessage("division() : La constante doit être un nombre",1); } } else if(_utilisateur->useRationnel()){ Rationnel *ra1; Rationnel *ra2; int choix=QMessageBox::Ok; if(typeid(*c1)!=typeid(Expression) && typeid(*c2)!=typeid(Expression)){ if(typeid(*c1)==typeid(Reel) || typeid(*c2)==typeid(Reel)){ choix=continuer(); } if(choix==QMessageBox::Ok){ Nombre * n1 = dynamic_cast<Nombre*>(c1); Nombre * n2 = dynamic_cast<Nombre*>(c2); ra1 = n1->toRationnel(); ra2 = n2->toRationnel(); } else{ _pileCourante->empilerConstante(c2); _pileCourante->empilerConstante(c1); throw LogMessage("division() : La constante doit être un nombre",1); } if(ra2->getNum()==0) throw LogMessage("division(): impossible de diviser par 0",1); else{ Rationnel * res = *(ra1)/ra2; _pileCourante->empilerConstante(res); savePileApresExe(); } } } else if(_utilisateur->useReel()){ Reel *re1; Reel *re2; int choix=QMessageBox::Ok; if(typeid(*c1)!=typeid(Expression) && typeid(*c2)!=typeid(Expression)){ if(typeid(*c1)==typeid(Rationnel) || typeid(*c2)==typeid(Rationnel)){ choix=continuer(); } if(choix==QMessageBox::Ok){ Nombre * n1 = dynamic_cast<Nombre*>(c1); Nombre * n2 = dynamic_cast<Nombre*>(c2); re1 = n1->toReel(); re2 = n2->toReel(); } else{ _pileCourante->empilerConstante(c2); _pileCourante->empilerConstante(c1); throw LogMessage("division() : La constante doit être un nombre",1); } if(re2->getReel()==0) throw LogMessage("division(): impossible de diviser par 0",1); else{ Reel * res = *(re1)/re2; _pileCourante->empilerConstante(res); savePileApresExe(); } } } else{ _pileCourante->empilerConstante(c2); _pileCourante->empilerConstante(c1); throw LogMessage("Type utilisé non reconnu",1); } } } } catch(LogMessage msg){ //La pile ne contenait pas au moins 2 éléments if(c2!=0) _pileCourante->empilerConstante(c2); if(c1!=0) _pileCourante->empilerConstante(c1); throw; } }
/*! \return Une reference sur une Constante contenant notre nouveau Rationnel. \sa <a href = "http://www.cplusplus.com/reference/clibrary/cmath/pow/">pow</a> */ Constante& Rationnel::cube()const { Rationnel* res = new Rationnel((int)pow((float)num,3), (int)pow((float)den,3)); res->simplifier(); return *res; }