Advertisement
Guest User

Untitled

a guest
May 20th, 2019
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.53 KB | None | 0 0
  1. #include "pch.h"
  2. #include <iostream>
  3. #include <vector>
  4.  
  5. class natural {
  6. private:
  7.     std::vector<uint32_t> value;
  8.  
  9. public:
  10.     /* Konstruktor bezargumentowy */
  11.     natural::natural() {}
  12.     /* Konstruktor kopiujacy, z uinta */
  13.     natural::natural(const uint32_t a) {
  14.         this->value.push_back(a);
  15.     }
  16.     /* Konstruktor kopiujacy, z vectora */
  17.     natural::natural(const std::vector<uint32_t> &a) {
  18.         this->value = a;
  19.     }
  20.     /* Konstruktor kopiujacy, z natural */
  21.     natural::natural(const natural &a) : value(a.value) {}
  22.  
  23.     /* Funkcja, ktora dodaje uinta32 do wartosci */
  24.     void natural::push_back(const uint32_t a) {
  25.         this->value.push_back(a);
  26.     }
  27.     /* Funkcja, ktora usuwa element o najwyzszej wadze */
  28.     void natural::pop_back() {
  29.         this->value.pop_back();
  30.     }
  31.     /* liczba elementow */
  32.     unsigned natural::size() {
  33.         return value.size();
  34.     }
  35.  
  36.     /* operator przypisania */
  37.     void natural::operator=(const natural &x) {
  38.         this->value = x.value;
  39.     }
  40.     /* operator porownania */
  41.     bool natural::operator==(const natural &x) {
  42.         if (value.size() != x.value.size())
  43.             return false;
  44.         else {
  45.             // porownywanie kolejnych elementow
  46.             for (unsigned i = 0; i < x.value.size(); i++)
  47.                 if (value[i] != x.value[i])
  48.                     return false;
  49.             return true;
  50.         }
  51.     }
  52.     /* operator inkrementacji */
  53.     void natural::operator++() {
  54.         unsigned i = 0;
  55.         bool cIn = true;
  56.         for (; i < this->value.size() && cIn; i++) {
  57.             this->value[i]++;
  58.             cIn = (this->value[i] == 0);
  59.         }
  60.         if (cIn) {
  61.             this->value.push_back(1);
  62.         }
  63.     }
  64.     /* operator dekrementacji */
  65.     void natural::operator--() {
  66.         if (this->value.size() == 0)
  67.             std::cout << "Niezainicjalizowana liczba";
  68.         int i = 0;
  69.         bool bIn = true;
  70.         for (; bIn; i++) {
  71.             bIn = (this->value[i] == 0);
  72.             this->value[i]--;
  73.         }
  74.     }
  75.  
  76.     /* operator porownania, wiekszy */
  77.     bool natural::operator >(const natural &x) {
  78.         if (this->value.size() > x.value.size())
  79.             return true;
  80.         else if (this->value.size() < x.value.size())
  81.             return false;
  82.         else { //argumenty tej samej dlugosci
  83.             // porownywanie kolejnych elementow od lewej (tych o wyzszej wadze)
  84.             for (int i = this->value.size() - 1; i >= 0; i--)
  85.                 if (this->value[i] > x.value[i])
  86.                     return true;
  87.             return false;
  88.         }
  89.     }
  90.     /* operator porownania, mniejszy */
  91.     bool natural::operator <(const natural &x) {
  92.         if (this->value.size() < x.value.size())
  93.             return true;
  94.         else if (this->value.size() > x.value.size())
  95.             return false;
  96.         else { //argumenty tej samej dlugosci
  97.             // porownywanie kolejnych elementow od lewej (tych o wyzszej wadze)
  98.             for (int i = this->value.size() - 1; i >= 0; i--)
  99.                 if (this->value[i] < x.value[i])
  100.                     return true;
  101.             return false;
  102.         }
  103.     }
  104.     /* operator porownania, wiekszy/rowny */
  105.     bool natural::operator >=(const natural &x) {
  106.         unsigned int counter = 0; //licznik rownych elementow
  107.         if (this->value.size() > x.value.size())
  108.             return true;
  109.         else if (this->value.size() < x.value.size())
  110.             return false;
  111.         else { //argumenty tej samej dlugosci
  112.             // sprawdzenie czy jest wiekszy
  113.             for (unsigned int i = this->value.size() - 1; i >= 0; i--) {
  114.                 if (this->value[i] > x.value[i])
  115.                     return true;
  116.                 else if (this->value[i] == x.value[i]) //sprawdzenie czy rowne
  117.                     counter++;
  118.             }
  119.             if (counter == this->value.size()) //wszystkie elementy sa rowne
  120.                 return true;
  121.             else
  122.                 return false;
  123.         }
  124.     }
  125.     /* operator porownania, mniejszy/rowny */
  126.     bool natural::operator <=(const natural &x) {
  127.         unsigned int counter = 0; //licznik rownych elementow
  128.         if (this->value.size() < x.value.size())
  129.             return true;
  130.         else if (this->value.size() > x.value.size())
  131.             return false;
  132.         else { //argumenty tej samej dlugosci
  133.             // sprawdzenie czy jest mniejszy
  134.             for (unsigned int i = this->value.size() - 1; i >= 0; i--) {
  135.                 if (this->value[i] < x.value[i])
  136.                     return true;
  137.                 else if (this->value[i] == x.value[i]) //sprawdzenie czy rowne
  138.                     counter++;
  139.             }
  140.             if (counter == this->value.size()) //wszystkie elementy sa rowne
  141.                 return true;
  142.             else
  143.                 return false;
  144.         }
  145.     }
  146.  
  147.     /* wypisywanie wartosci */
  148.     void natural::print() {
  149.         for (int i = value.size() - 1; i >= 0; i--)
  150.             std::cout << value[i] << " ";
  151.         std::cout << "\n";
  152.     }
  153.     /* usuwanie wiodacego zera */
  154.     void natural::eraseLeadingZeroIfExists() {
  155.         if ((this->value.size() - 1) == 0) //jesli elementem o najwyzszej wadze jest 0
  156.             this->value.pop_back(); //trzeba je usunac, zaburza wykonanie porownania
  157.     }
  158.  
  159.     /* operacje arytmetyczne */
  160.     /* dodawanie */
  161.     void natural::add(const natural &x, const natural &y) {
  162.         bool cIn, cOut; //przeniesienia na konkretnych pozycjach
  163.         uint32_t temp; //przechowywanie sumy
  164.         unsigned i = 0; //indeksowanie
  165.  
  166.         const natural *shorterArg, *longerArg; //zmienne na krotszy i dluzszy argument
  167.         if (x.value.size() >= y.value.size()) { //rownej dlugosci lub x dluzszy od y
  168.             longerArg = &x;
  169.             shorterArg = &y;
  170.         }
  171.         else { //y dluzszy od x
  172.             longerArg = &y;
  173.             shorterArg = &x;
  174.         }
  175.         // dla kazdego elementu w zasiegu krotszego argumentu
  176.         for (cIn = false; i < shorterArg->value.size(); i++) {
  177.             temp = longerArg->value[i] + shorterArg->value[i];
  178.             cOut = (temp < longerArg->value[i]); //sprawdzenie czy uint sie "nie przekrecil"
  179.             if (cIn) {
  180.                 temp++;
  181.                 cOut |= (temp == 0); // cOut | temp
  182.             }
  183.             this->value.push_back(temp); // zapisanie wyniku
  184.             cIn = cOut; // przeniesienie w nastepnej iteracji
  185.         }
  186.         //w zasiegu dluzszego argumentu z przeniesieniem
  187.         for (; i < longerArg->value.size() && cIn; i++) {
  188.             temp = longerArg->value[i] + 1;
  189.             cIn = (temp == 0); //max val + 1 = 0
  190.             this->value.push_back(temp);
  191.         }
  192.         //w zasiegu dluzszego argumentu bez przeniesienia
  193.         for (; i < longerArg->value.size(); i++)
  194.             this->value.push_back(longerArg->value[i]); //przepisywanie
  195.         //Dodatkowy element w przypadku nadmiaru
  196.         if (cIn)
  197.             this->value.push_back(1);
  198.     }
  199.     /* odejmowanie */
  200.     void natural::subtract(const natural &x, const natural &y) {
  201.         bool bIn, bOut; //pozyczki na konkretnych pozycjach
  202.         uint32_t temp; //przechowywanie roznicy
  203.         unsigned i = 0; //indeksowanie
  204.  
  205.         for (bIn = false; i < y.value.size(); i++) {
  206.             temp = x.value[i] - y.value[i];
  207.             bOut = (temp > x.value[i]); //sprawdzenie czy uint sie "nie przekrecil"
  208.             if (bIn) {
  209.                 bOut |= (temp == 0); // bOut | temp
  210.                 temp--;
  211.             }
  212.             this->value.push_back(temp); // zapisanie wyniku
  213.             bIn = bOut; // pozyczka w nastepnej iteracji
  214.         }
  215.         // dalsze pozyczki
  216.         for (; i < x.value.size() && bIn; i++) {
  217.             bIn = (x.value[i] == 0);
  218.             this->value.push_back(x.value[i] - 1);
  219.         }
  220.         if (bIn) {
  221.             this->value.clear();
  222.             std::cout << "Wynik odejmowania ujemny\n";
  223.         }
  224.         else //dalsze przepisywanie odjemnej, bez zmian
  225.             for (; i < x.value.size(); i++)
  226.                 this->value.push_back(x.value[i]);
  227.     }
  228.     /* mnozenie */
  229.     void natural::multiply(const natural &x, const natural &y) {
  230.         int cIn = 0;
  231.         int cOut = 0;
  232.         uint32_t temp = 0;
  233.         std::vector<uint32_t> tempMod;
  234.         natural tempVec;
  235.         natural tempNat;
  236.         int longerArg = 0;
  237.         if (x.value.size() >= y.value.size())
  238.             longerArg = x.value.size();
  239.         else longerArg = y.value.size();
  240.  
  241.         unsigned long long longtemp;
  242.         for (unsigned i = 0; i < x.value.size(); i++) {
  243.             for (int k = 0; k < i; k++) {
  244.                 tempVec.value.insert(tempVec.value.begin(), 0);
  245.             }
  246.             for (unsigned j = 0; j < y.value.size(); j++) {
  247.                 longtemp = x.value[i] * y.value[j] + cIn;
  248.                 temp = longtemp;
  249.                 tempVec.value.insert(tempVec.value.begin() + i + j, temp);
  250.                 if (temp == longtemp) {
  251.                     cIn = 0;
  252.                 }
  253.                 else {
  254.                     cIn = longtemp / 4294967295;
  255.                 }
  256.                 temp = 0;
  257.  
  258.             }
  259.             tempMod = this->value;
  260.             tempNat.value = tempMod;
  261.             this->value.clear();
  262.             this->add(tempNat, tempVec);
  263.             tempVec.value.clear();
  264.             tempMod.clear();
  265.         }
  266.     }
  267.  
  268.     // prymitywny algorytm dzielenia
  269.     void natural::divide(const natural &x, const natural &y) {
  270.         natural divident(x); //kopia do dzialan dzielnej
  271.         natural quotient(0); //przechowywanie ilorazu, quotient
  272.         natural temp;
  273.  
  274.         while (divident.operator>(y)) { //powinno byc >= ale samo > to mniej operacji
  275.             temp.subtract(divident, y);
  276.             divident.value = temp.value; //kopiowanie wartosci
  277.             divident.print();
  278.             temp.value.clear(); //zwalnianie pamieci z temp
  279.             quotient.operator++();
  280.             divident.eraseLeadingZeroIfExists();
  281.         }
  282.         if (divident.operator==(y)) { //ostatnie porownanie
  283.             temp.subtract(divident, y);
  284.             divident.value = temp.value; //kopiowanie wartosci
  285.             temp.value.clear(); //zwalnianie pamieci z temp
  286.             quotient.operator++();
  287.         }
  288.         this->value = quotient.value;
  289.         temp.value.clear(); //zwalnianie pamieci z temp
  290.         divident.value.clear();
  291.     }
  292.  
  293. };
  294.  
  295. class smNum
  296. {
  297.     bool sign; //false +, true -
  298.     natural module; //modul reprezentowany przez liczbe naturalna
  299. public:
  300.     bool static getSign(smNum x) {
  301.         return x.sign;
  302.     }
  303.  
  304.     natural static getModule(smNum x) {
  305.         return x.module;
  306.     }
  307.     /* Konstruktor bezargumentowy */
  308.     smNum::smNum()
  309.         : sign(false),
  310.         module() { }
  311.     /* Konstruktor kopiujacy, z uinta */
  312.     smNum::smNum(const uint32_t a) {
  313.         sign = false;
  314.         this->module.push_back(a);
  315.     }
  316.     /* Konstruktor sam modul */
  317.     smNum::smNum(const std::vector<uint32_t> &a) {
  318.         sign = false;
  319.         module = natural(a);
  320.     }
  321.  
  322.     /* Konstruktor znak-modul */
  323.     smNum::smNum(bool si, const std::vector<uint32_t> &a) {
  324.         sign = si;
  325.         module = natural(a);
  326.     }
  327.  
  328.     /* Konstruktor kopiujacy z smNum */
  329.     smNum::smNum(const smNum &b)
  330.         : sign(b.sign),
  331.         module(b.module) { }
  332.  
  333.     /* Konstruktor kopiujacy znak + natural */
  334.     smNum::smNum(const bool si, const natural &n)
  335.         : sign(si),
  336.         module(n) { }
  337.  
  338.     /* Konstruktor kopiujacy z natural */
  339.     smNum::smNum(const natural &n)
  340.         : sign(false),
  341.         module(n) { }
  342.  
  343.     /* Konstruktor z konwersja z typu long long */
  344.     smNum::smNum(long long value)
  345.     {
  346.         if (value < 0) {
  347.             sign = true;
  348.             module = natural(0);
  349.         }
  350.         else {
  351.             sign = false;
  352.         }
  353.  
  354.         while (value) {
  355.             module.push_back((uint32_t)(value));
  356.         }
  357.     }
  358.  
  359.     /* wypisywanie wartosci */
  360.     void smNum::print() {
  361.         if (sign)
  362.             std::cout << "- ";
  363.         else
  364.             std::cout << "+ ";
  365.  
  366.         module.print();
  367.     }
  368.  
  369.     /* operator przypisania */
  370.     void smNum::operator=(const smNum &x) {
  371.         this->sign = x.sign;
  372.         this->module = x.module;
  373.     }
  374.     /* operator porownania */
  375.     bool smNum::operator==(const smNum &x) {
  376.         if (this->sign != x.sign) //jesli znaki sa rozne false
  377.             return false;
  378.         else //porownanie wartosci
  379.             if (this->module == x.module)
  380.                 return true;
  381.             else
  382.                 return false;
  383.     }
  384.     /* operator inkrementacji */
  385.     void smNum::operator++() {
  386.         if (!sign) //dodatnie
  387.             this->module.operator++();
  388.         else //ujemne
  389.             this->module.operator--();
  390.     }
  391.     /* operator dekrementacji */
  392.     void smNum::operator--() {
  393.         if (!sign) //dodatnie
  394.             this->module.operator--();
  395.         else //ujemne
  396.             this->module.operator++();
  397.     }
  398.  
  399.     /* operator porownania, wiekszy */
  400.     bool smNum::operator >(const smNum &x) {
  401.         if (this->sign != x.sign) { //znaki rozne
  402.             if (this->sign == 0 && x.sign == 1) //x jest liczba ujemna
  403.                 return true;
  404.             else
  405.                 return false; //x dodatnie a liczba ujemna
  406.         }
  407.         else { //znaki zgodne
  408.             if (this->sign == 0) { //obie liczby dodatnie
  409.                 if (this->module > x.module)
  410.                     return true;
  411.                 else
  412.                     return false;
  413.             }
  414.             else { //obie liczby ujemne
  415.                 if (this->module < x.module)
  416.                     return true;
  417.                 else
  418.                     return false;
  419.             }
  420.         }
  421.     }
  422.     /* operator porownania, mniejszy */
  423.     bool smNum::operator <(const smNum &x) {
  424.         if (this->sign != x.sign) { //znaki rozne
  425.             if (this->sign == 0 && x.sign == 1) //x jest liczba ujemna
  426.                 return false;
  427.             else
  428.                 return true; //x dodatnie a liczba ujemna
  429.         }
  430.         else { //znaki zgodne
  431.             if (this->sign == 0) { //obie liczby dodatnie
  432.                 if (this->module < x.module)
  433.                     return true;
  434.                 else
  435.                     return false;
  436.             }
  437.             else { //obie liczby ujemne
  438.                 if (this->module > x.module)
  439.                     return true;
  440.                 else
  441.                     return false;
  442.             }
  443.         }
  444.     }
  445.     /* operator porownania, wiekszy/rowny */
  446.     bool smNum::operator >=(const smNum &x) {
  447.         if (this->sign != x.sign) { //znaki rozne
  448.             if (this->sign == 0 && x.sign == 1) //x jest liczba ujemna
  449.                 return true;
  450.             else
  451.                 return false; //x dodatnie a liczba ujemna
  452.         }
  453.         else { //znaki zgodne
  454.             if (this->sign == 0) { //obie liczby dodatnie
  455.                 if (this->module >= x.module)
  456.                     return true;
  457.                 else
  458.                     return false;
  459.             }
  460.             else { //obie liczby ujemne
  461.                 if (this->module <= x.module)
  462.                     return true;
  463.                 else
  464.                     return false;
  465.             }
  466.         }
  467.     }
  468.     /* operator porownania, mniejszy/rowny */
  469.     bool smNum::operator <=(const smNum &x) {
  470.         if (this->sign != x.sign) { //znaki rozne
  471.             if (this->sign == 0 && x.sign == 1) //x jest liczba ujemna
  472.                 return false;
  473.             else
  474.                 return true; //x dodatnie a liczba ujemna
  475.         }
  476.         else { //znaki zgodne
  477.             if (this->sign == 0) { //obie liczby dodatnie
  478.                 if (this->module <= x.module)
  479.                     return true;
  480.                 else
  481.                     return false;
  482.             }
  483.             else { //obie liczby ujemne
  484.                 if (this->module >= x.module)
  485.                     return true;
  486.                 else
  487.                     return false;
  488.             }
  489.         }
  490.     }
  491.     smNum smNum::operator+(smNum x) {
  492.         smNum result;
  493.         smNum arg(this->sign, this->module);
  494.         result.add(arg, x);
  495.         return result;
  496.     }
  497.     smNum smNum::operator-(smNum x) {
  498.         smNum result;
  499.         smNum arg(this->sign, this->module);
  500.         result.sub(arg, x);
  501.         return result;
  502.     }
  503.     smNum smNum::operator*(smNum x) {
  504.         smNum result;
  505.         smNum arg(this->sign, this->module);
  506.         result.mul(arg, x);
  507.         return result;
  508.     }
  509.     smNum smNum::operator/(smNum x) {
  510.         smNum result;
  511.         smNum arg(this->sign, this->module);
  512.         result.div(arg, x);
  513.         return result;
  514.     }
  515.     /* operacje arytmetyczne */
  516.     // dodawanie
  517.     void smNum::add(smNum x, smNum y) {
  518.         if (x.sign == y.sign) { //znaki zgodne
  519.             this->sign = x.sign;
  520.             this->module.add(x.module, y.module);
  521.         }
  522.         else { //znaki niezgodne
  523.             if (x.module >= y.module) {
  524.                 this->sign = x.sign;
  525.                 this->module.subtract(x.module, y.module);
  526.             }
  527.             else
  528.             {
  529.                 this->sign = y.sign;
  530.                 this->module.subtract(y.module, x.module);
  531.             }
  532.         }
  533.     }
  534.     // odejmowanie
  535.     void smNum::sub(smNum x, smNum y) {
  536.         if (x.sign == y.sign) { //znaki zgodne
  537.             if (x.module >= y.module) {
  538.                 this->sign = x.sign;
  539.                 this->module.subtract(x.module, y.module);
  540.             }
  541.             else
  542.             {
  543.                 this->sign = !(x.sign);
  544.                 this->module.subtract(y.module, x.module);
  545.             }
  546.         }
  547.         else { //znaki niezgodne
  548.             this->sign = x.sign;
  549.             if (x.sign == 0) {
  550.                 this->module.add(x.module, y.module);
  551.             }
  552.             else
  553.             {
  554.                 this->module.add(x.module, y.module);
  555.             }
  556.         }
  557.     }
  558.     // mnozenie
  559.     void smNum::mul(smNum x, smNum y) {
  560.         if (x.sign == y.sign)
  561.             this->sign = 0;
  562.         else
  563.             this->sign = 1;
  564.  
  565.         this->module.multiply(x.module, y.module);
  566.     }
  567.     // prymitywny algorytm dzielenia
  568.     void smNum::div(smNum x, smNum y) {
  569.         if (x.sign == y.sign)
  570.             this->sign = 0;
  571.         else
  572.             this->sign = 1;
  573.  
  574.         this->module.divide(x.module, y.module);
  575.     }
  576.    
  577. };
  578.  
  579. bool equals(const smNum &x, const smNum &y) {
  580.  
  581.     if (x.getSign(x) != y.getSign(y)) //jesli znaki sa rozne false
  582.         return false;
  583.     else //porownanie wartosci
  584.         if (x.getModule(x) == y.getModule(y))
  585.             return true;
  586.         else
  587.             return false;
  588. }
  589. int Factorial(int n) {
  590.     int result = 1;
  591.     for (int i = 1; i <= n; i++) {
  592.         result *= i;
  593.     }
  594.  
  595.     return result;
  596. }
  597. TEST(TestDodawania, Dodawanie) {
  598.     std::vector<uint32_t> vect;
  599.     std::vector<uint32_t> vect2;
  600.     vect.push_back(55);
  601.     vect.push_back(1);
  602.     vect2.push_back(16);
  603.     vect2.push_back(1);
  604.     std::vector<uint32_t> vect3;
  605.     vect3.push_back(2);
  606.     vect3.push_back(71);
  607.     smNum wynik;//(vect3);
  608.     smNum a1(vect);
  609.     smNum a2(vect2);
  610.     wynik.add(a1, a2);
  611.     smNum a3;
  612.     a3.add(a1, a2);
  613.     a3.print();
  614.     wynik.print();
  615.   ASSERT_TRUE(equals(a3,wynik));
  616. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement