Numere complexe in C++
#1
Posted 22 October 2014 - 19:10
De curand am facut si eu o mica biblioteca in C++ cu numere complexe si m-am gandit sa v-o prezint si voua.
Spoiler
Am pus codul sub forma de spoiler deoarece este cam maricel...undeva pe la 400 de linii de cod. O sa postez si un main.cpp pentru a vedea cum se foloseste biblioteca (desi majoritatea va dadeati seama singuri). #include "ComplexNumber.h" #include <stdexcept> void afisareOptiuni() { cout << "Optiuni:\n"; cout << "0. Iesire\n"; cout << "1. Adunare\n"; cout << "2. Scadere\n"; cout << "3. Inmultire\n"; cout << "4. Impartire\n"; cout << "5. Ridicare la putere\n"; cout << "6. Conjugat\n"; cout << "7. Adunare cu un scalar\n"; cout << "8. Inmultire cu un scalar\n"; cout << "9. Impartire cu un scalar\n"; cout << "10. Scadere cu un scalar\n"; cout << "11. Inmultire cu conjugatul\n"; } int main(void) { int optiune; float nr; ComplexNumber n1, n2, rezultat; afisareOptiuni(); while (1) { cout << "\nAlegeti o optiune: "; cin >> optiune; switch (optiune) { case 0 : break; case 1 : cout << "Introduceti primul numar: "; cin >> n1; cout << "Introduceti al doilea numar: "; cin >> n2; rezultat = n1 + n2; cout << "Rezultatul este: " << rezultat << endl; break; case 2 : cout << "Introduceti primul numar: "; cin >> n1; cout << "Introduceti al doilea numar: "; cin >> n2; rezultat = n1 - n2; cout << "Rezultatul este: " << rezultat << endl; break; case 3 : cout << "Introduceti primul numar: "; cin >> n1; cout << "Introduceti al doilea numar: "; cin >> n2; rezultat = n1 * n2; cout << "Rezultatul este: " << rezultat << endl; break; case 4 : cout << "Introduceti primul numar: "; cin >> n1; cout << "Introduceti al doilea numar: "; cin >> n2; rezultat = n1 / n2; cout << "Rezultatul este: " << rezultat << endl; break; case 5 : cout << "Introduceti numarul complex: "; cin >> n1; cout << "Introduceti puterea: "; int p; cin >> p; n1.power(p); cout << "Rezultatul este: " << n1 << endl; break; case 6 : cout << "Introduceti numarul complex: "; cin >> n1; rezultat = !n1; cout << "Conjugatul este: " << rezultat << endl; break; case 7 : cout << "Introduceti un numar complex: "; cin >> n1; cout << "Introduceti un numar real: "; cin >> nr; rezultat = n1 + nr; cout << "Rezultatul este: " << rezultat << endl; break; case 8 : cout << "Introduceti un numar complex: "; cin >> n1; cout << "Introduceti un numar real: "; cin >> nr; rezultat = n1 * nr; cout << "Rezultatul este: " << rezultat << endl; break; case 9 : cout << "Introduceti un numar complex: "; cin >> n1; cout << "Introduceti un numar real: "; cin >> nr; rezultat = n1 / nr; cout << "Rezultatul este: " << rezultat << endl; break; case 10 : cout << "Introduceti un numar complex: "; cin >> n1; cout << "Introduceti un numar real: "; cin >> nr; rezultat = n1 - nr; cout << "Rezultatul este: " << rezultat << endl; break; case 11 : cout << "Introduceti primul numar: "; cin >> n1; n2 = n1; rezultat = n2 * !n1; cout << "Rezultatul este: " << rezultat << endl; break; } if (optiune == 0) break; } return 0; } Cam asta-i biblioteca...astept sugestii si/sau critici |
#2
Posted 22 October 2014 - 19:24
Nu m-am uitat cu extrem de multa atentie pe cod, dar as sugera sa parametrizezi tipul de baza pentru partile reala respectiv imaginara prin template-uri.
Arata scris curat oricum. |
#3
Posted 22 October 2014 - 19:29
Dupa o privire superficiala:
1. Cel mai bine ar fi ca clasa respectiva sa fie o clasa template (parametrul template sa fie tipul partii reale si al partii imaginare) 2. Nu are rost sa faci clasa respectiva derivabila 3. Majoritatea functiilor membre ar trebui sa fie inline 4. Scoate codul ce afiseaza pe consola, n-are ce cauta acolo 5. Nu mai folosi using namespace std in headere 6. N-ai unit-teste ? Edited by xyv123, 22 October 2014 - 19:33. |
#4
Posted 22 October 2014 - 19:29
Si membrii privati ar putea avea denumiri mai sugestive, nu a si b.
Edited by tatarduka, 22 October 2014 - 19:30. |
#5
Posted 22 October 2014 - 19:34
Overloading pentru >> si << chiar nu aduce o atat de multa plus-valoare incat sa merite legarea de stdlibc++.
La derivabila e discutabila. Eu nu as impiedica asta, decat intr-o aplicatie complexa, in care arhitectura cere o astfel de masura. Ori aici e vorba doar de o clasa, o biblioteca, si, fiind biblioteca, vrei ca ea sa fie reutilizabila. Nu poti sti cine o va folosi si cum, vrei sa lasi deschisa aceasta optiune. |
#6
Posted 22 October 2014 - 19:40
Arată bine. Ai putea să îi adaugi și funcția modul și poate și o funcție care întoarce argumentul.
|
#7
Posted 22 October 2014 - 19:47
In plus, trage un ochi peste o implementare de std::complex, de exemplu asta din STLport:
https://github.com/s.../stl/_complex.h |
#8
Posted 22 October 2014 - 19:51
OriginalCopy, on 22 octombrie 2014 - 19:24, said:
Nu m-am uitat cu extrem de multa atentie pe cod, dar as sugera sa parametrizezi tipul de baza pentru partile reala respectiv imaginara prin template-uri. Arata scris curat oricum. xyv123, on 22 octombrie 2014 - 19:29, said:
Dupa o privire superficiala: 1. Cel mai bine ar fi ca clasa respectiva sa fie o clasa template (parametrul template sa fie tipul partii reale si al partii imaginare) 2. Nu are rost sa faci clasa respectiva derivabila 3. Majoritatea functiilor membre ar trebui sa fie inline 4. Scoate codul ce afiseaza pe consola, n-are ce cauta acolo 5. Nu mai folosi using namespace std in headere 6. N-ai unit-teste ? 2. Deocamdata nu stiu sa o faca nederivabila, dar ma voi interesa. 4. La care cod te referi? 5. Am inteles. 6. Nu. tatarduka, on 22 octombrie 2014 - 19:29, said:
Si membrii privati ar putea avea denumiri mai sugestive, nu a si b. xyv123, on 22 octombrie 2014 - 19:47, said:
In plus, trage un ochi peste o implementare de std::complex, de exemplu asta din STLport: https://github.com/s.../stl/_complex.h O sa ma uit... adrian93, on 22 octombrie 2014 - 19:40, said:
Arată bine. Ai putea să îi adaugi și funcția modul și poate și o funcție care întoarce argumentul. Edited by EnachescuAlin, 22 October 2014 - 19:50. |
#9
Posted 22 October 2014 - 19:55
4. Nu folosi cod ce afiseaza pe stdout/stderr in implementarea bibliotecii.
De exemplu, in implementarea din operator>>, ai: cout << "Introdu un numar complex valid: "; Nu are ce sa caute asa ceva acolo. Edited by xyv123, 22 October 2014 - 19:56. |
#10
Posted 22 October 2014 - 20:00
|
#11
Posted 22 October 2014 - 20:21
Hint: Ai grija la impartirea cu 0. Vezi daca nu-ti crapa programul la impartirea unui numar complex cu 0. LE: Nu am vazut spoilerul, kill me... 1.Da, la impartirea cu 0 iti va da crash. Trebuie sa arunci o exceptie in momentul intalnirii lui 0 ca numitor, ca altfel nu merge. 2. N-ai tratat cazul puterea 0, deci la power=0 se comporta imprevizibil programul Ce a zis OriginalCopy e necesar. Presupunand ca vreau un numar complex, cu partile reale si imaginare numere rationale(de tipul 2/3, 3/5), numere rationale fiind definite intr-o alta biblioteca. Ce faci? Nu prea poti face nimic, deoarece tu le-ai setat float. Edited by Rhesus, 22 October 2014 - 20:46. |
#12
Posted 22 October 2014 - 20:51
Rhesus, on 22 octombrie 2014 - 20:21, said: Hint: Ai grija la impartirea cu 0. Vezi daca nu-ti crapa programul la impartirea unui numar complex cu 0. LE: Nu am vazut spoilerul, kill me... 1.Da, la impartirea cu 0 iti va da crash. Trebuie sa arunci o exceptie in momentul intalnirii lui 0 ca numitor, ca altfel nu merge. 2. N-ai tratat cazul puterea 0, deci la power=0 se comporta imprevizibil programul Ce a zis OriginalCopy e necesar. Presupunand ca vreau un numar complex, cu partile reale si imaginare numere rationale(de tipul 2/3, 3/5), numere rationale fiind definite intr-o alta biblioteca. Ce faci? Nu prea poti face nimic, deoarece tu le-ai setat float. 1. Mie nu-mi da crash...imi da inf+infi. 2. Il voi trata. |
#13
Posted 22 October 2014 - 20:56
Fa power sa fie defapt un overloading pt ^ . E mai frumos. A, si neaparat in clasa. Respecta principiul de incapsulare a datelor!
Altele: 1. Ai putea face un cast de la float la complexe, ca sa nu trebuiasca sa faci nspe mii de overloading-uri pt. +=,-= ... O singura metoda pt. fiecare operator 2. Iti lipseste minusul unar (si plusul unar, care nu face nimic, dar ,,legal” trebuie sa fie). 3. Ai putea adauga o metoda pt. modulul unui nr. complex si conjugatul unui nr. complex. Alege eventual niste simboluri cu care sa te joci. Edited by Rhesus, 22 October 2014 - 21:04. |
#14
Posted 22 October 2014 - 21:20
Rhesus, on 22 octombrie 2014 - 20:56, said:
Fa power sa fie defapt un overloading pt ^ . E mai frumos. A, si neaparat in clasa. Respecta principiul de incapsulare a datelor! Altele: 1. Ai putea face un cast de la float la complexe, ca sa nu trebuiasca sa faci nspe mii de overloading-uri pt. +=,-= ... O singura metoda pt. fiecare operator 2. Iti lipseste minusul unar (si plusul unar, care nu face nimic, dar ,,legal” trebuie sa fie). 3. Ai putea adauga o metoda pt. modulul unui nr. complex si conjugatul unui nr. complex. Alege eventual niste simboluri cu care sa te joci. 2. Nu te-ai uitat tu bine... 3. Pentru conjugat exista... |
#15
Posted 22 October 2014 - 21:33
|
#16
Posted 22 October 2014 - 21:44
Rhesus, on 22 octombrie 2014 - 21:33, said:
2. Ai doar --, si ++ . - unar nu vad. Adica: complexnumber operator- (); 3. Il caut. L-am gasit. E ok atunci ComplexNumber ComplexNumber::operator-(float value) { ComplexNumber other(a, ; other[0] -= value; return other; } ComplexNumber ComplexNumber::operator-(const ComplexNumber& number) { return ComplexNumber(a - number.GetReal(), b - number.GetImaginary()); } Edited by EnachescuAlin, 22 October 2014 - 21:44. |
#17
Posted 22 October 2014 - 22:50
Nu e bine. Minusul unar, inseamna minus obiectul tau (in cazul nostru nr. complex). Ce ai acolo, e o scadere intre un numar complex si o valoare value de tip float!
ComplexNumber ComplexNumber::operator-() { ComplexNumber other(-a,-; return other; } // Daca ai obiectul ob=2+3i, -ob este defapt -2-3i. Asta e operatorul - unar, pe post de prefix Operatorul - (minus) se comporta in 3 feluri: 1. operatie intre 2 operanzi (exact cum ai facut tu, cu float value pe post de al doilea operand) 2. operatie cu un singur operand, pe post de prefix (adica inaintea obiectului): in acest caz, nu introduci nimic la parametrii formali ai functiei 3. operatie cu un singur operand, pe post de sufix (adica dupa obiect): in acest caz, introduci un int simplu in lista parametrilor formali, fara a exista un al doilea operand. Int are rolul de a mentiona ca vorbim de operandul in pozitie postfixa(sufix) si nu prefix. http://www.cplusplus.com/ LE: Operatorul + unar, nu va face nimic (nu schimba nimic in intelegere). Dar se implementeaza, ca si cum nu ar face nimic. ComplexNumber ComplexNumber::operator+ () { } Edited by Rhesus, 22 October 2014 - 22:55. |
Anunturi
▶ 0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users