Guest User

Nytrp

a guest
Mar 27th, 2011
4,310
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 23.72 KB | None | 0 0
  1.  
  2. /*
  3.     Nume: Popescu Ionut Gabriel
  4.     Tema: Numere reale mari
  5.     Continut: Definitia clasei pentru lucrul cu numere reale mari
  6. */
  7.  
  8. /*
  9.     Observatie
  10.         nr : 0.222 - double
  11.         nr_prec : 0.2219999999999942 - reprezentarea sa (precizie 16)
  12.     Sau:
  13.         nr : 0.456
  14.         nr_prec : 0.4560000000000031 - reprezentarea sa (precizie 16)
  15. */
  16.  
  17. // Prevenire multi-incluziune
  18.  
  19. #ifndef BIGREAL_H_INCLUDED
  20. #define BIGREAL_H_INCLUDED
  21.  
  22. // Pentru supraincarcare << si >>
  23.  
  24. #include <iostream>
  25. #include <fstream>
  26.  
  27. // O cifra ce foloseste 4 biti in loc de 8
  28. // Mai putina memorie folosita (1/2)
  29. // Pentru posibile implementari ulterioare
  30.  
  31. struct cifra_mica
  32. {
  33.     unsigned char c: 4;
  34. };
  35.  
  36. // Macro, daca e cifra
  37.  
  38. #define e_cifra(x) (x >= '0' && x <= '9' ? 1 : 0)
  39.  
  40. // Modul de depanare
  41.  
  42. #define DEBUG 0
  43.  
  44. // Definitia clasei
  45.  
  46. class BigReal
  47. {
  48.     private:
  49.  
  50.         char *intreg, *zecimal;  // Vectori pentru cifre
  51.         bool semn;               // Daca numarul e pozitiv sau negativ
  52.  
  53.         // Metode ajutatoare
  54.  
  55.         char* intreg_la_sir(int x);                              // Convertire de la intreg la sir de caractere
  56.         char* zecimala_la_sir(double x);                         // Convertire parte zecimala la sir
  57.         char* aduna_siruri(const char *sir1, const char *sir2);  // Adunare 2 siruri de caractere
  58.  
  59.     public:
  60.  
  61.         // Constructori si destructor
  62.  
  63.         BigReal();                 // Constructor fara parametri
  64.         BigReal(int x);            // Constructor cu parametru int
  65.         BigReal(double x);         // Constructor cu parametru double
  66.         BigReal(const char *sir);  // Constructor cu parametru sir
  67.         BigReal(BigReal &ob);      // Constructor de copiere
  68.         ~BigReal();                // Destructor
  69.  
  70.         // Supraincarcare operator +
  71.  
  72.         BigReal& operator + (int x);                                // BigReal + int
  73.         BigReal& operator + (double x);                             // BigReal + double
  74.         BigReal& operator + (const char *sir);                      // BigReal + sir
  75.         BigReal& operator + (BigReal &ob);                          // BigReal + BigReal
  76.         friend BigReal& operator + (int x, BigReal &ob);            // int + BigReal
  77.         friend BigReal& operator + (double x, BigReal &ob);         // double + BigReal
  78.         friend BigReal& operator + (const char *sir, BigReal &ob);  // sir + BigReal
  79.  
  80.         // Supraincarcare operator binar -
  81.  
  82.         BigReal& operator - (int x);                                // BigReal - int
  83.         BigReal& operator - (double x);                             // BigReal - double
  84.         BigReal& operator - (const char *sir);                      // BigReal - sir
  85.         BigReal& operator - (BigReal &ob);                          // BigReal - BigReal
  86.         friend BigReal& operator - (int x, BigReal &ob);            // int - BigReal
  87.         friend BigReal& operator - (double x, BigReal &ob);         // double - BigReal
  88.         friend BigReal& operator - (const char *sir, BigReal &ob);  // sir - BigReal
  89.  
  90.         // Supraincarcare operatori unar - si +
  91.  
  92.         BigReal& operator - ();  // - BigReal
  93.         BigReal& operator + ();  // + BigReal
  94.  
  95.         // Supraincarcare operator binar *
  96.  
  97.         BigReal& operator * (int x);                                // BigReal * int
  98.         BigReal& operator * (double x);                             // BigReal * double
  99.         BigReal& operator * (const char *sir);                      // BigReal * sir
  100.         BigReal& operator * (BigReal &ob);                          // BigReal * BigReal
  101.         friend BigReal& operator * (int x, BigReal &ob);            // int * BigReal
  102.         friend BigReal& operator * (double x, BigReal &ob);         // double * BigReal
  103.         friend BigReal& operator * (const char *sir, BigReal &ob);  // sir * BigReal
  104.  
  105.         // Supraincarcare operator /
  106.  
  107.         BigReal& operator / (int x);                                // BigReal / int
  108.         BigReal& operator / (double x);                             // BigReal / double
  109.         BigReal& operator / (const char *sir);                      // BigReal / sir
  110.         BigReal& operator / (BigReal &ob);                          // BigReal / BigReal
  111.         friend BigReal& operator / (int x, BigReal &ob);            // int / BigReal
  112.         friend BigReal& operator / (double x, BigReal &ob);         // double / BigReal
  113.         friend BigReal& operator / (const char *sir, BigReal &ob);  // sir / BigReal
  114.  
  115.         // Supraincarcare operator <
  116.  
  117.         BigReal& operator < (int x);                                // BigReal < int
  118.         BigReal& operator < (double x);                             // BigReal < double
  119.         BigReal& operator < (const char *sir);                      // BigReal < sir
  120.         BigReal& operator < (BigReal &ob);                          // BigReal < BigReal
  121.         friend BigReal& operator < (int x, BigReal &ob);            // int < BigReal
  122.         friend BigReal& operator < (double x, BigReal &ob);         // double < BigReal
  123.         friend BigReal& operator < (const char *sir, BigReal &ob);  // sir < BigReal
  124.  
  125.         // Supraincarcare operator <=
  126.  
  127.         BigReal& operator <= (int x);                                // BigReal <= int
  128.         BigReal& operator <= (double x);                             // BigReal <= double
  129.         BigReal& operator <= (const char *sir);                      // BigReal <= sir
  130.         BigReal& operator <= (BigReal &ob);                          // BigReal <= BigReal
  131.         friend BigReal& operator <= (int x, BigReal &ob);            // int <= BigReal
  132.         friend BigReal& operator <= (double x, BigReal &ob);         // double <= BigReal
  133.         friend BigReal& operator <= (const char *sir, BigReal &ob);  // sir <= BigReal
  134.  
  135.         // Supraincarcare operator >
  136.  
  137.         BigReal& operator > (int x);                                // BigReal > int
  138.         BigReal& operator > (double x);                             // BigReal > double
  139.         BigReal& operator > (const char *sir);                      // BigReal > sir
  140.         BigReal& operator > (BigReal &ob);                          // BigReal > BigReal
  141.         friend BigReal& operator > (int x, BigReal &ob);            // int > BigReal
  142.         friend BigReal& operator > (double x, BigReal &ob);         // double > BigReal
  143.         friend BigReal& operator > (const char *sir, BigReal &ob);  // sir > BigReal
  144.  
  145.         // Supraincarcare operator <=
  146.  
  147.         BigReal& operator >= (int x);                                // BigReal >= int
  148.         BigReal& operator >= (double x);                             // BigReal >= double
  149.         BigReal& operator >= (const char *sir);                      // BigReal >= sir
  150.         BigReal& operator >= (BigReal &ob);                          // BigReal >= BigReal
  151.         friend BigReal& operator >= (int x, BigReal &ob);            // int >= BigReal
  152.         friend BigReal& operator >= (double x, BigReal &ob);         // double >= BigReal
  153.         friend BigReal& operator >= (const char *sir, BigReal &ob);  // sir >= BigReal
  154.  
  155.         // Supraincarcare operator ==
  156.  
  157.         BigReal& operator == (int x);                                // BigReal == int
  158.         BigReal& operator == (double x);                             // BigReal == double
  159.         BigReal& operator == (const char *sir);                      // BigReal == sir
  160.         BigReal& operator == (BigReal &ob);                          // BigReal == BigReal
  161.         friend BigReal& operator == (int x, BigReal &ob);            // int == BigReal
  162.         friend BigReal& operator == (double x, BigReal &ob);         // double == BigReal
  163.         friend BigReal& operator == (const char *sir, BigReal &ob);  // sir == BigReal
  164.  
  165.         // Supraincarcare operator !=
  166.  
  167.         BigReal& operator != (int x);                                // BigReal != int
  168.         BigReal& operator != (double x);                             // BigReal != double
  169.         BigReal& operator != (const char *sir);                      // BigReal != sir
  170.         BigReal& operator != (BigReal &ob);                          // BigReal != BigReal
  171.         friend BigReal& operator != (int x, BigReal &ob);            // int != BigReal
  172.         friend BigReal& operator != (double x, BigReal &ob);         // double != BigReal
  173.         friend BigReal& operator != (const char *sir, BigReal &ob);  // sir != BigReal
  174.  
  175.         // Supraincarcare operator =
  176.  
  177.         BigReal& operator = (int x);                                // BigReal = int
  178.         BigReal& operator = (double x);                             // BigReal = double
  179.         BigReal& operator = (const char *sir);                      // BigReal = sir
  180.         BigReal& operator = (BigReal &ob);                          // BigReal = BigReal
  181.  
  182.         // Supraincarcare operatori cast
  183.  
  184.         operator int ();     // int = BigReal
  185.         operator double ();  // double = BigReal
  186.         operator char* ();   // sir = BigReal
  187.  
  188.         // Supraincarcare << si >> pentru cout si cin
  189.  
  190.         friend std::ostream& operator << (std::ostream &flux, BigReal &ob);  // cout << BigReal
  191.         friend std::istream& operator >> (std::istream &flux, BigReal &ob);  // cin >> BigReal
  192.  
  193.         // Supraincarcare operator ++
  194.  
  195.         BigReal& operator ++ ();       // ++ BigReal
  196.         BigReal& operator ++ (int x);  // BigReal ++
  197.  
  198.         // Supraincarcare operator --
  199.  
  200.         BigReal& operator -- ();       // -- BigReal
  201.         BigReal& operator -- (int x);  // BigReal --
  202.  
  203.         // Functii pentru acces la date, publice, inline
  204.  
  205.         char* intoarce_intreg() { return intreg; }    // Intoarce pointerul catre partea intreaga
  206.         char* intoarce_zecimal() { return zecimal; }  // Intoarce pointerul catre partea zecimala
  207.  
  208.         // Atribuire de valori pentru datele private
  209.  
  210.         void atribuie_intreg(const char *sir);
  211.         void atribuie_zecimal(const char *sir);
  212.  
  213.         // DE FACUT: Definitii supraincarcare:
  214.         // - operator +=, -=, *=, /=
  215. };
  216.  
  217. // Constructor fara parametri
  218.  
  219. BigReal::BigReal()
  220. {
  221.     if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal()"<<std::endl;
  222.  
  223.     // Alocare spatiu pentru intreg si zecimal si setare la 0.0
  224.  
  225.     intreg = new char[2];
  226.     intreg[0] = '0';
  227.     intreg[1] = '\0';
  228.  
  229.     zecimal = new char[2];
  230.     zecimal[0] = '0';
  231.     zecimal[1] = '\0';
  232.  
  233.     semn = true;
  234. }
  235.  
  236. // Constructor cu parametru int
  237.  
  238. BigReal::BigReal(int x)
  239. {
  240.     if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal(int)"<<std::endl;
  241.  
  242.     // Partea intreaga
  243.  
  244.     intreg = intreg_la_sir(x);
  245.  
  246.     // Partea zecimala e 0
  247.  
  248.     zecimal = new char[2];
  249.     zecimal[0] = '0';
  250.     zecimal[1] = '\0';
  251. }
  252.  
  253. // Constructor cu parametru double
  254.  
  255. BigReal::BigReal(double x)
  256. {
  257.     if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal(double)"<<std::endl;
  258.  
  259.     // Pentru partea intreaga, convertim pe aceasta la sir
  260.  
  261.     intreg = intreg_la_sir((int)x);
  262.  
  263.     // Pentru partea zecimala folosim functia
  264.  
  265.     zecimal = zecimala_la_sir(x);
  266. }
  267.  
  268. // Constructorul pentru parametru sir de caractere
  269.  
  270. BigReal::BigReal(const char *sir)
  271. {
  272.     if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal(const char*)"<<std::endl;
  273.  
  274.     int i, j, rest = 0;
  275.  
  276.     // Parcurgem sirul de caractere pana la "." sau ","
  277.  
  278.     for(i = 0; sir[i] && (sir[i] != '.') && (sir[i] != ','); i++) {}
  279.  
  280.     // Alocam spatiu (i) pentru partea intreaga si o copiem
  281.  
  282.     intreg = new char[i + 1];
  283.  
  284.     for(j = 0; j < i; j++) intreg[j] = sir[j];
  285.     intreg[j] = '\0';
  286.  
  287.     // Parcurgem sa vedem cate cifre are partea zecimala
  288.  
  289.     for(j = i + 1; sir[j]; j++) rest++;
  290.  
  291.     // Copiem partea zecimala
  292.  
  293.     zecimal = new char[rest + 1];
  294.  
  295.     for(j = i + 1; j < i + rest + 1; j++) zecimal[j - i - 1] = sir[j];
  296.     zecimal[j - i - 1] = '\0';
  297. }
  298.  
  299. // Constructorul de copiere
  300.  
  301. BigReal::BigReal(BigReal &ob)
  302. {
  303.     if(DEBUG) std::cout<<"DEBUG: BigReal::BigReal(BigReal&)"<<std::endl;
  304.  
  305.     char *ps;
  306.     int i, j;
  307.  
  308.     // Citim partea intreaga si preluam marimea
  309.  
  310.     ps = ob.intoarce_intreg();
  311.     for(i = 0; ps[i]; i++) {}
  312.  
  313.     // Alocam spatiu pentru partea intreaga si copiem din ob
  314.  
  315.     intreg = new char[i + 1];
  316.     for(j = 0; j < i; j++) intreg[j] = ps[j];
  317.     intreg[j] = '\0';
  318.  
  319.     // Citim partea zecimala si preluam marimea
  320.  
  321.     ps = ob.intoarce_zecimal();
  322.     for(i = 0; ps[i]; i++) {}
  323.  
  324.     // Alocam spatiu pentru partea intreaga si copiem din ob
  325.  
  326.     zecimal = new char[i + 1];
  327.     for(j = 0; j < i; j++) zecimal[j] = ps[j];
  328.     zecimal[j] = '\0';
  329. }
  330.  
  331. // Supraincarcare operator + pentru adunare BigReal + int
  332.  
  333. BigReal& BigReal::operator + (int x)
  334. {
  335.     if(DEBUG) std::cout<<"DEBUG: BigReal::operator + (int)"<<std::endl;
  336.  
  337.     BigReal *tmp = new BigReal();
  338.  
  339.     // Atribuim valorile adunate pointerului pe care il vom returna
  340.  
  341.     tmp -> atribuie_intreg(aduna_siruri(this -> intreg, intreg_la_sir(x)));
  342.     tmp -> atribuie_zecimal(this -> zecimal);
  343.  
  344.     return *tmp;
  345. }
  346.  
  347. // Supraincarcare operator + pentru adunare BigReal + double
  348.  
  349. BigReal& BigReal::operator + (double x)
  350. {
  351.     if(DEBUG) std::cout<<"DEBUG: BigReal::operator + (double)"<<std::endl;
  352.  
  353.     BigReal *tmp = new BigReal();
  354.  
  355.     // Atribuim valorile adunate pointerului pe care il vom returna
  356.  
  357.     tmp -> atribuie_intreg(aduna_siruri(this -> intreg, intreg_la_sir(x)));
  358.     tmp -> atribuie_zecimal(aduna_siruri(this -> zecimal, zecimala_la_sir(x)));
  359.  
  360.     return *tmp;
  361. }
  362.  
  363. // Supraincarcare operator + pentru adunare BigReal + BigReal
  364.  
  365. BigReal& BigReal::operator + (BigReal &ob)
  366. {
  367.     if(DEBUG) std::cout<<"DEBUG: BigReal::operator + (BigReal)"<<std::endl;
  368.  
  369.     BigReal *tmp = new BigReal();
  370.  
  371.     // Atribuim valorile adunate pointerului pe care il vom returna
  372.  
  373.     tmp -> atribuie_intreg(aduna_siruri(this -> intreg, ob.intoarce_intreg()));
  374.     tmp -> atribuie_zecimal(aduna_siruri(this -> zecimal, ob.intoarce_zecimal()));
  375.  
  376.     return *tmp;
  377. }
  378.  
  379. // Supraincarcare operator + pentru adunare BigReal + const char *
  380.  
  381. BigReal& BigReal::operator + (const char *sirx)
  382. {
  383.     if(DEBUG) std::cout<<"DEBUG: BigReal::operator + (const char *)"<<std::endl;
  384.  
  385.     BigReal *tmp = new BigReal();
  386.  
  387.     // Copiem sirul din parametru intr-un alt sir pentru ca trebuie sa il modificam
  388.  
  389.     int l = 0, k;
  390.     while(sirx[l++]);
  391.  
  392.     char *sir = new char[l];
  393.     for(k = 0; k < l - 1; k++) sir[k] = sirx[k];
  394.     sir[k] = '\0';
  395.  
  396.     // Obtinem lungimea
  397.  
  398.     int i = 0;
  399.     for(i = 0; sir[i] && sir[i] != '.' && sir[i] != ','; i++) {}
  400.  
  401.     // Daca contine "," sau "."
  402.  
  403.     if(sir[i] == ',' || sir[i] == '.') tmp -> atribuie_zecimal(&sir[i + 1]);
  404.     else tmp -> atribuie_zecimal("0");
  405.  
  406.     // Partea ntreaga
  407.  
  408.     if(i == 0) tmp -> atribuie_intreg("0");
  409.     else
  410.     {
  411.         // Un mic truc pentru viteza mai mare, la partea zecimala plecam de unde incepe
  412.         // Punem NULL unde e virgula (pozitia i) ca sa putem folosi partea intreaga ca sir, direct
  413.  
  414.         sir[i] = '\0';
  415.  
  416.         tmp -> atribuie_intreg(sir);
  417.     }
  418.  
  419.     // Atribuim valorile adunate pointerului pe care il vom returna
  420.  
  421.     tmp -> atribuie_intreg(aduna_siruri(this -> intreg, tmp -> intoarce_intreg()));
  422.     tmp -> atribuie_zecimal(aduna_siruri(this -> zecimal, tmp -> intoarce_zecimal()));
  423.  
  424.     return *tmp;
  425. }
  426.  
  427. // Supraincarcare operator + pentru adunare int + BigReal
  428.  
  429. BigReal& operator + (int x, BigReal &ob)
  430. {
  431.     return ob + x;
  432. }
  433.  
  434. // Supraincarcare operator + pentru adunare double + BigReal
  435.  
  436. BigReal& operator + (double x, BigReal &ob)
  437. {
  438.     return ob + x;
  439. }
  440.  
  441. // Supraincarcare operator + pentru adunare const char* + BigReal
  442.  
  443. BigReal& operator + (const char *x, BigReal &ob)
  444. {
  445.     return ob + x;
  446. }
  447.  
  448. // Supraincarcare operator * pentru BigReal * int
  449.  
  450. BigReal& BigReal::operator * (int x)
  451. {
  452.     if(DEBUG) std::cout<<"DEBUG: BigReal::operator * (int)"<<std::endl;
  453.  
  454.     BigReal *tmp = new BigReal();
  455.  
  456.     // Adunam de x ori si partea intreaga si partea zecimala
  457.  
  458.     for(int i = 1; i <= x; i++)
  459.     {
  460.         tmp -> atribuie_intreg(aduna_siruri(tmp -> intoarce_intreg(), this -> intreg));
  461.         tmp -> atribuie_zecimal(aduna_siruri(tmp -> intoarce_zecimal(), this -> zecimal));
  462.     }
  463.  
  464.     return *tmp;
  465. }
  466.  
  467. // Supraincarcare operator * pentru int * BigReal
  468.  
  469. BigReal& operator * (int x, BigReal &ob)
  470. {
  471.     return ob * x;
  472. }
  473.  
  474. // Destructorul
  475.  
  476. BigReal::~BigReal()
  477. {
  478.     if(DEBUG) std::cout<<"DEBUG: BigReal::~BigReal()"<<std::endl;
  479.  
  480.     // Eliberare memorie
  481.  
  482.     delete[] intreg;
  483.     delete[] zecimal;
  484. }
  485.  
  486. // Conversie manuala a partii zecimale a unui double la sir de caractere
  487.  
  488. char* BigReal::zecimala_la_sir(double x)
  489. {
  490.     if(DEBUG == 2) std::cout<<"DEBUG: zecimala_la_sir(double)"<<std::endl;
  491.  
  492.     double nr;
  493.     // int cif, contor0 = 0, contor9 = 0, cifre = 0;
  494.     int lungime_cif = 0, i;
  495.     char cifrute[19];
  496.  
  497.     char *parte_zecimala;
  498.  
  499.     // Partea zecimala a parametrului
  500.  
  501.     nr = x - (int)x;
  502.  
  503.     // Stupid: scriem in fisier
  504.  
  505.     std::fstream f("F:/test.txt", std::ios::out);
  506.     f<<nr;
  507.     f.close();
  508.  
  509.     // Citim ca sir din fisier
  510.  
  511.     std::fstream g("F:/test.txt", std::ios::in);
  512.     g>>cifrute;
  513.     g.close();
  514.  
  515.     // Copiem partea zecimala si o returnam
  516.  
  517.     while(cifrute[lungime_cif++]);
  518.  
  519.     parte_zecimala = new char[lungime_cif - 2];
  520.     for(i = 0; i < lungime_cif - 3; i++) parte_zecimala[i] = cifrute[i + 2];
  521.     parte_zecimala[i] = '\0';
  522.  
  523. /*
  524.     // Parcurgem partea zecimala pana intalnim 000000
  525.  
  526.     while(nr != (double)(int)nr && contor0 <= 6 && contor9 <= 6)
  527.     {
  528.         cif = (int)(nr * 10);
  529.  
  530.         // Verificam daca suntem la secventa de 000000 sau 999999
  531.  
  532.         if(cif == 0) contor0++;
  533.         else contor0 = 0;
  534.  
  535.         if(cif == 9) contor9++;
  536.         else contor0 = 9;
  537.  
  538.         // Punem cifra in vector si incrementam numarul cifrei
  539.  
  540.         cifrute[cifre] = cif + 48;
  541.         cifre++;
  542.  
  543.         nr = double(nr * 10) - (double)(int)(nr * 10);
  544.     }
  545.  
  546.     // Alocam spatiu pentru partea zecimala
  547.  
  548.     parte_zecimala = new char[cifre - 6];
  549.  
  550.     // Copiem cifrele din sirul temporar in partea zecimala
  551.  
  552.     for(i = 0; i < cifre - 7; i++) parte_zecimala[i] = cifrute[i];
  553.     parte_zecimala[i] = '\0';
  554.  
  555.     // Returnam pointerul
  556. */
  557.     return parte_zecimala;
  558. }
  559.  
  560. // Conversie manuala de la int la sir de caractere
  561.  
  562. char* BigReal::intreg_la_sir(int x)
  563. {
  564.     if(DEBUG == 2) std::cout<<"DEBUG: intreg_la_sir(int)"<<std::endl;
  565.  
  566.     char sir[11];  // Maxim 10 cifre (+ \0)
  567.     int i = 0, j;
  568.  
  569.     // Daca x == 0
  570.  
  571.     if(x == 0)
  572.     {
  573.         // Partea intreaga va fi 0
  574.  
  575.         intreg = new char[2];
  576.         intreg[0] = '0';
  577.         intreg[1] = '\0';
  578.     }
  579.  
  580.     // Daca nu, il transformam in sir
  581.  
  582.     else
  583.     {
  584.         while(x)
  585.         {
  586.             sir[i++] = x % 10 + 48;  // Codul ASCII al cifrei
  587.             x = x / 10;
  588.         }
  589.         sir[i] = '\0';
  590.  
  591.         // Alocam spatiu pentru intreg
  592.  
  593.         intreg = new char[i];
  594.  
  595.         // Copiem din sirul local in sirul "intreg", ordine inversa
  596.  
  597.         for(j = 0; j < i; j++) intreg[j] = sir[i - j - 1];
  598.  
  599.         intreg[i] = '\0';
  600.     }
  601.  
  602.     return intreg;
  603. }
  604.  
  605. // Functie pentru setarea valorii intregi a obiectului
  606.  
  607. void BigReal::atribuie_intreg(const char *sir)
  608. {
  609.     if(DEBUG == 2) std::cout<<"DEBUG: atribuie_intreg(const char *)"<<std::endl;
  610.  
  611.     int i, j;
  612.  
  613.     // Daca e deja alocat, eliberam memoria si o alocam din nou, apoi copiem sirul
  614.  
  615.     if(intreg) delete[] intreg;
  616.  
  617.     for(i = 0; sir[i] && e_cifra(sir[i]); i++) {}
  618.  
  619.     intreg = new char[i + 1];
  620.  
  621.     for(j = 0; j < i; j++) intreg[j] = sir[j];
  622.     intreg[j] = '\0';
  623. }
  624.  
  625. // Functie pentru setarea valorii zecimale a obiectului
  626.  
  627. void BigReal::atribuie_zecimal(const char *sir)
  628. {
  629.     if(DEBUG == 2) std::cout<<"DEBUG: atribuie_zecimal(const char *)"<<std::endl;
  630.  
  631.     int i, j;
  632.  
  633.     // Daca e deja alocat, eliberam memoria si o alocam din nou, apoi copiem sirul
  634.  
  635.     if(zecimal) delete[] zecimal;
  636.  
  637.     for(i = 0; sir[i] && e_cifra(sir[i]); i++) {}
  638.  
  639.     zecimal = new char[i + 1];
  640.  
  641.     for(j = 0; j < i; j++) zecimal[j] = sir[j];
  642.     zecimal[j] = '\0';
  643. }
  644.  
  645. // Functie ce preia ca parametri 2 siruri de caractere, NUMERE si returneaza suma lor ca sir
  646.  
  647. char* BigReal::aduna_siruri(const char *sir1, const char *sir2)
  648. {
  649.     if(DEBUG == 2) std::cout<<"DEBUG: aduna_siruri(const char *, const char *)"<<std::endl;
  650.  
  651.     // Determinam rapid lungimile sirurilor
  652.  
  653.     int lun_1 = 0, lun_2 = 0, ultim;
  654.     while(sir1[lun_1++]);
  655.     while(sir2[lun_2++]);
  656.  
  657.     // Pozitia ultimei cifre
  658.  
  659.     ultim = lun_1 > lun_2 ? lun_1 : lun_2;
  660.     ultim++;
  661.  
  662.     // Alocam spatiu pentru noul sir
  663.  
  664.     char *suma_s = new char[ultim];
  665.     suma_s[(--ultim)--] = '\0';
  666.  
  667.     int transport = 0, i, j;
  668.     i = lun_1 - 1;
  669.     j = lun_2 - 1;
  670.  
  671.     // Facem adunarea cat timp avem acelasi nr. de cifre
  672.  
  673.     int mic = i < j ? i : j;
  674.     i--;
  675.     j--;
  676.  
  677.     while(mic--)
  678.     {
  679.         // Daca suma e 0-9
  680.  
  681.         if(sir1[i] + sir2[j] + transport < 106)
  682.         {
  683.             suma_s[ultim--] = sir1[i] + sir2[j] + transport - 48;  // Cifra din suma celor 2 cifre
  684.             transport = 0;
  685.         }
  686.  
  687.         // Daca depaseste 9
  688.  
  689.         else
  690.         {
  691.             suma_s[ultim--] = sir1[i] + sir2[j] + transport - 58;  // Cifra din suma celor 2 cifre
  692.             transport = 1;
  693.         }
  694.  
  695.         i--;
  696.         j--;
  697.     }
  698.  
  699.     i++;
  700.     j++;
  701.  
  702.     // Pentru numar egal de cifre, daca avem sau nu transport
  703.  
  704.     if(i == 0 && j == 0)
  705.     {
  706.         if(transport) suma_s[0] = '1';
  707.         else
  708.         {
  709.             // Daca nu, cream un nou sir, fara prima cifra (pentru transport)
  710.  
  711.             char *final;
  712.             int k, lungime = lun_1 > lun_2 ? lun_1 : lun_2;
  713.             final = new char[lungime];
  714.             for(k = 1; k < lungime; k++) final[k - 1] = suma_s[k];
  715.             final[k - 1] = '\0';
  716.             return final;
  717.         }
  718.     }
  719.  
  720.     //Completam cu cifrele numarului cu mai multe cifre
  721.  
  722.     if(i)
  723.     {
  724.         // Parcurgem sirul ` si nu uitam de transport
  725.  
  726.         while(i)
  727.         {
  728.             i--;
  729.  
  730.             // Daca e 0
  731.  
  732.             if(sir1[i] + transport == 58)
  733.             {
  734.                 suma_s[ultim--] = sir1[i] + transport - 10;
  735.                 transport = 1;
  736.             }
  737.             else
  738.             {
  739.                 suma_s[ultim--] = sir1[i] + transport;
  740.                 transport = 0;
  741.             }
  742.         }
  743.  
  744.         // Daca avem transport, pe prima pozitie avem 1
  745.  
  746.         if(transport) suma_s[0] = '1';
  747.         else
  748.         {
  749.             // Daca nu, cream un nou sir, fara prima cifra (pentru transport)
  750.  
  751.             char *final;
  752.             int k, lungime = lun_1 > lun_2 ? lun_1 : lun_2;
  753.             final = new char[lungime];
  754.             for(k = 1; k < lungime; k++) final[k - 1] = suma_s[k];
  755.             final[k - 1] = '\0';
  756.             return final;
  757.         }
  758.     }
  759.     else if(j)
  760.     {
  761.         // Parcurgem sirul 2 si nu uitam de transport
  762.  
  763.         while(j)
  764.         {
  765.             j--;
  766.  
  767.             // Daca e 0
  768.  
  769.             if(sir2[j] + transport == 58)
  770.             {
  771.                 suma_s[ultim--] = sir2[j] + transport - 10;
  772.                 transport = 1;
  773.             }
  774.             else
  775.             {
  776.                 suma_s[ultim--] = sir2[j] + transport;
  777.                 transport = 0;
  778.             }
  779.         }
  780.  
  781.         // Daca avem transport, pe prima pozitie avem 1
  782.  
  783.         if(transport) suma_s[0] = '1';
  784.         else
  785.         {
  786.             // Daca nu, cream un nou sir, fara prima cifra (pentru transport)
  787.  
  788.             char *final;
  789.             int k, lungime = lun_1 > lun_2 ? lun_1 : lun_2;
  790.             final = new char[lungime];
  791.             for(k = 1; k < lungime; k++) final[k - 1] = suma_s[k];
  792.             final[k - 1] = '\0';
  793.             return final;
  794.         }
  795.     }
  796.  
  797.     // Returnam suma
  798.  
  799.     return suma_s;
  800. }
  801.  
  802. // Supraincarcare oeprator << pentru afisare
  803.  
  804. std::ostream& operator << (std::ostream& flux, BigReal& ob)
  805. {
  806.     if(DEBUG == 2) std::cout<<"DEBUG: operator << (std::ostream&, BigReal&)"<<std::endl;
  807.  
  808.     // Afisam partea intreaga si partea zecimala
  809.  
  810.     flux << ob.intoarce_intreg();
  811.     flux << '.';
  812.     flux << ob.intoarce_zecimal();
  813.  
  814.     // Returnam fluxu, pentru operatii imbricate
  815.  
  816.     return flux;
  817. }
  818.  
  819. // Supraincarcare oeprator >> pentru citire (cu ".", "," si filtrare non-cifre)
  820.  
  821. std::istream& operator >> (std::istream& flux, BigReal& ob)
  822. {
  823.     if(DEBUG == 2) std::cout<<"DEBUG: operator >> (std::istream&, BigReal&)"<<std::endl;
  824.  
  825.     char sir[1000];
  826.     int i;
  827.  
  828.     // Atribuim valorile: intreaga si zecimala obiectului ob, dupa citire
  829.  
  830.     flux >> sir;
  831.     for(i = 0; sir[i] && sir[i] != '.' && sir[i] != ','; i++) {}
  832.  
  833.     // Daca contine "," sau "."
  834.  
  835.     if(sir[i] == ',' || sir[i] == '.') ob.atribuie_zecimal(&sir[i + 1]);
  836.     else ob.atribuie_zecimal("0");
  837.  
  838.     // Partea ntreaga
  839.  
  840.     if(i == 0) ob.atribuie_intreg("0");
  841.     else
  842.     {
  843.         // Un mic truc pentru viteza mai mare, la partea zecimala plecam de unde incepe
  844.         // Punem NULL unde e virgula (pozitia i) ca sa putem folosi partea intreaga ca sir, direct
  845.  
  846.         sir[i] = '\0';
  847.  
  848.         ob.atribuie_intreg(sir);
  849.     }
  850.  
  851.     // Returnam fluxu, pentru operatii imbricate
  852.  
  853.     return flux;
  854. }
  855.  
  856. #endif // BIGREAL_H_INCLUDED
Advertisement
Add Comment
Please, Sign In to add comment