From 3688793c1c351e1c0e297c504de1a1803d620a75 Mon Sep 17 00:00:00 2001 From: mahmoudrizk Date: Sun, 26 Feb 2017 18:27:29 +0200 Subject: [PATCH 1/7] Fixing Bug with big number multiplication --- src/bigint.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bigint.cpp b/src/bigint.cpp index 6fff39e..e685629 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -118,7 +118,9 @@ Bigint &Bigint::operator+=(long long b) number.insert(number.end(), skip - number.size(), 0); } it += skip; - while (b) { + bool initial_flag=true; + while (b || initial_flag) { + initial_flag=false; if (it != number.end()) { *it += b % base; b /= base; From 7846e33432dacb33626dcb8efb8074713696bd87 Mon Sep 17 00:00:00 2001 From: mahmoudrizk Date: Mon, 6 Mar 2017 17:56:40 +0200 Subject: [PATCH 2/7] Adding Division operation --- src/bigint.cpp | 132 ++++++++++++++++++++++++++++++++++++++++++++++++- src/bigint.h | 4 ++ 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/src/bigint.cpp b/src/bigint.cpp index e685629..163ba46 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -2,6 +2,7 @@ #include #include #include "bigint.h" +#include namespace Dodecahedron { @@ -119,7 +120,7 @@ Bigint &Bigint::operator+=(long long b) } it += skip; bool initial_flag=true; - while (b || initial_flag) { + while (b || initial_flag) { initial_flag=false; if (it != number.end()) { *it += b % base; @@ -190,7 +191,7 @@ Bigint Bigint::operator*(Bigint const &b) if (b.number.size() == 1) return *this *= b.number[0]; std::vector::iterator it1; std::vector::const_iterator it2; - Bigint c; + Bigint c("0"); for (it1 = number.begin(); it1 != number.end(); ++it1) { for (it2 = b.number.begin(); it2 != b.number.end(); ++it2) { c.skip = (unsigned int) (it1 - number.begin()) + (it2 - b.number.begin()); //TODO @@ -232,7 +233,133 @@ Bigint &Bigint::operator*=(int const &b) return *this; } +Bigint Bigint::sub_number(Bigint &p, Bigint &q){ + + std::string tmpx0, tmpx1, tmpx3; + long window_size = q.digits(); + int last_i_iterator; + std::vector::iterator i=p.number.end()-1; + + if(window_size>p.digits()) + window_size=p.digits(); + + + while(i>=p.number.begin() && window_size>0){ + + tmpx0 = to_string(*i); + int ssss = tmpx0.size(); + if(i!=p.number.end()-1 && ssss<9){ + tmpx0 = std::string(9-ssss,'0') + tmpx0; + } + + if(window_size - ssss < 0){ + tmpx3=tmpx0; + tmpx0=""; + for(int i=0;i=p.number.begin()){ + if(tmpx3.size()!=0){ + window_size++; + tmpx0 = tmpx3[last_i_iterator+1]; + tmpx1 = tmpx1 + tmpx0; + c=tmpx1; + } + else{ + window_size++; + tmpx0 = to_string(*i); + if(i!=p.number.end()-1 && tmpx0.size()<9){ + tmpx0 = std::string(9-tmpx0.size(),'0') + tmpx0; + } + tmpx0 = tmpx0[0]; + tmpx1 = tmpx1 + tmpx0; + c=tmpx1; + } + + } + + return c; +} +//Division +std::vector Bigint::operator/(Bigint q){ + + /*Algorithm used is "Double division algorithm"*/ + + Bigint p = *this; + std::vector answer; + int look_up_table_size=4; + std::vector look_up(look_up_table_size); + bool done_flag=false ; + Bigint tmp_quotient, sum_quotient, tmpx1, tmpx2; + + look_up[0]=q; + look_up[1]=q*2; + look_up[2]=q*4; + look_up[3]=q*8; + + while(true){ + + Bigint sub_p=sub_number(p, q); // cut a portion from the dividened equal in size with the divisor + + for(int i=0;i=p.digits()){ + done_flag=true; + break; + } + } + else if(sub_p==look_up[i] || (sub_p>look_up[i] && i==look_up_table_size-1)){ + tmpx1=look_up[i]; + tmp_quotient= std::pow(2,i); + break; + } + } + + if(done_flag){ + answer.push_back(sum_quotient); + answer.push_back(sub_p); + break; + } + + std::string temppp(p.digits()-(sub_p.digits()),'0'); + temppp="1"+temppp; + tmpx2=temppp; + + if(sum_quotient.digits()==0) + sum_quotient=tmp_quotient*tmpx2; + else + sum_quotient=sum_quotient+(tmp_quotient*tmpx2); + + tmpx1=tmpx1*tmpx2; + p=p-tmpx1; + + } + return answer; + +} + //Power + Bigint Bigint::pow(int const &power, std::map &lookup) { if (power == 1) return *this; @@ -394,6 +521,7 @@ std::ostream &operator<<(std::ostream &out, Bigint a) return out; } + std::istream &operator>>(std::istream &in, Bigint &a) { std::string str; diff --git a/src/bigint.h b/src/bigint.h index d090bcb..605e661 100644 --- a/src/bigint.h +++ b/src/bigint.h @@ -38,6 +38,9 @@ class Bigint Bigint operator*(long long const &); Bigint &operator*=(int const &); + //Division + std::vector operator/(Bigint q); // returns quotient(index[0]) and remainder(index[1]) + //Compare bool operator<(const Bigint &) const; bool operator>(const Bigint &) const; @@ -69,6 +72,7 @@ class Bigint int segment_length(int) const; Bigint pow(int const &, std::map &); int compare(Bigint const &) const; //0 a == b, -1 a < b, 1 a > b + Bigint sub_number(Bigint &p, Bigint &q); // used in the division function }; Bigint abs(Bigint); From 5f160accb79f2913b41411f9a40b7c17b5941d18 Mon Sep 17 00:00:00 2001 From: MahmoudRizk Date: Mon, 6 Mar 2017 18:06:31 +0200 Subject: [PATCH 3/7] Update README.md --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 70f1899..b2ea383 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ * [Addition](#addition) * [Subtraction](#subtraction) * [Multiplication](#multiplication) + * [Division](#division) * [Allocation](#allocation) * [Comparison](#comparison) * [Access](#access) @@ -46,6 +47,17 @@ c *= a; c = a * 6; c *= 6; ``` +##Division +```C++ +Dodecahedron::Bigint a,b; +std::vector c; +Dodecahedron::Bigint quotient, remainder ; + +c = a / b; + +quotient = c[0]; +remainder = c[1]; +``` ##Allocation ```C++ Dodecahedron::Bigint a = 12345; From 7e9d1cac829764ba4dfee3065650be0f98564b29 Mon Sep 17 00:00:00 2001 From: mahmoudrizk Date: Sat, 11 Mar 2017 14:23:46 +0200 Subject: [PATCH 4/7] fixing division by zero & fixing signed number division 'quotient only is correct in case of signed numbers division' --- src/bigint.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++- src/bigint.h | 1 + 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/bigint.cpp b/src/bigint.cpp index 163ba46..7d8597f 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -3,6 +3,7 @@ #include #include "bigint.h" #include +#include namespace Dodecahedron { @@ -233,6 +234,26 @@ Bigint &Bigint::operator*=(int const &b) return *this; } +bool Bigint::is_even(){ + if(number.size()==1){ + int x = number[0]; + if(x%2 == 0) + return true; + else + return false; + } + + else if(number.size()>1){ + int x = *(number.begin()); + if(x%2 == 0) + return true; + else + return false; + } + +} + + Bigint Bigint::sub_number(Bigint &p, Bigint &q){ std::string tmpx0, tmpx1, tmpx3; @@ -305,11 +326,25 @@ std::vector Bigint::operator/(Bigint q){ bool done_flag=false ; Bigint tmp_quotient, sum_quotient, tmpx1, tmpx2; + Bigint zero("0"); + if(q==zero){ + std::cout << "Error: Dividing by zero" << std::endl; + exit (EXIT_FAILURE); + } + + bool this_sign = this -> positive; + bool q_sign = q.positive; + + p.positive = true; + q.positive = true; + + look_up[0]=q; look_up[1]=q*2; look_up[2]=q*4; look_up[3]=q*8; + while(true){ Bigint sub_p=sub_number(p, q); // cut a portion from the dividened equal in size with the divisor @@ -354,8 +389,26 @@ std::vector Bigint::operator/(Bigint q){ p=p-tmpx1; } - return answer; + if(this_sign == false && q_sign == false){ + answer[0].positive = true; + } + + else if(this_sign == false || q_sign == false){ + if( this -> is_even() && q.is_even()) + answer[0].positive = false; + else{ + answer[0] = answer[0] + Bigint("1"); + answer[0].positive = false; + } + } + + else{ + answer[0].positive = true; + } + + return answer; + } //Power @@ -573,3 +626,4 @@ Bigint factorial(int n) } } + diff --git a/src/bigint.h b/src/bigint.h index 605e661..6e87303 100644 --- a/src/bigint.h +++ b/src/bigint.h @@ -39,6 +39,7 @@ class Bigint Bigint &operator*=(int const &); //Division + bool is_even(); std::vector operator/(Bigint q); // returns quotient(index[0]) and remainder(index[1]) //Compare From 30f3714fdecf6815db0b385c4b6d18bcbf95667d Mon Sep 17 00:00:00 2001 From: mahmoudrizk Date: Sun, 12 Mar 2017 00:08:15 +0200 Subject: [PATCH 5/7] handling division by zero error in better way --- src/bigint.cpp | 28 ++++++++++++++++++++++------ src/bigint.h | 6 ++++-- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/bigint.cpp b/src/bigint.cpp index 7d8597f..8f0ed1c 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -4,6 +4,7 @@ #include "bigint.h" #include #include +#include namespace Dodecahedron { @@ -315,7 +316,8 @@ Bigint Bigint::sub_number(Bigint &p, Bigint &q){ return c; } //Division -std::vector Bigint::operator/(Bigint q){ + +std::vector Bigint::divide(Bigint q){ /*Algorithm used is "Double division algorithm"*/ @@ -327,9 +329,11 @@ std::vector Bigint::operator/(Bigint q){ Bigint tmp_quotient, sum_quotient, tmpx1, tmpx2; Bigint zero("0"); - if(q==zero){ - std::cout << "Error: Dividing by zero" << std::endl; - exit (EXIT_FAILURE); + + if(q==zero || q == 0){ + //std::cout << "Error: Dividing by zero" << std::endl; + //exit (EXIT_FAILURE); + throw "Dividing by zero!"; } bool this_sign = this -> positive; @@ -408,9 +412,22 @@ std::vector Bigint::operator/(Bigint q){ } return answer; - + } +std::vector Bigint::operator/(Bigint q){ + try{ + return divide(q); + } + catch(const char* msg){ + std::cerr << msg << std::endl; + std::terminate(); + } + + +} + + //Power Bigint Bigint::pow(int const &power, std::map &lookup) @@ -626,4 +643,3 @@ Bigint factorial(int n) } } - diff --git a/src/bigint.h b/src/bigint.h index 6e87303..a0d97e6 100644 --- a/src/bigint.h +++ b/src/bigint.h @@ -40,8 +40,10 @@ class Bigint //Division bool is_even(); - std::vector operator/(Bigint q); // returns quotient(index[0]) and remainder(index[1]) - + private: + std::vector divide(Bigint q); // returns quotient(index[0]) and remainder(index[1]). + public: + std::vector operator/(Bigint q); // interface for divide() function. //Compare bool operator<(const Bigint &) const; bool operator>(const Bigint &) const; From 85adfe0915699c6a3720ae8e3e074c7ef385b7b2 Mon Sep 17 00:00:00 2001 From: mahmoudrizk Date: Mon, 13 Mar 2017 14:31:19 +0200 Subject: [PATCH 6/7] cleaning code 'removing commented code' --- src/bigint.cpp | 4 +- src/bigint.cpp~ | 643 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 644 insertions(+), 3 deletions(-) create mode 100644 src/bigint.cpp~ diff --git a/src/bigint.cpp b/src/bigint.cpp index 8f0ed1c..d268ea4 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -331,9 +331,7 @@ std::vector Bigint::divide(Bigint q){ Bigint zero("0"); if(q==zero || q == 0){ - //std::cout << "Error: Dividing by zero" << std::endl; - //exit (EXIT_FAILURE); - throw "Dividing by zero!"; + throw "Dividing by zero!"; } bool this_sign = this -> positive; diff --git a/src/bigint.cpp~ b/src/bigint.cpp~ new file mode 100644 index 0000000..4009e0f --- /dev/null +++ b/src/bigint.cpp~ @@ -0,0 +1,643 @@ +#include +#include +#include +#include "bigint.h" +#include +#include +#include + +namespace Dodecahedron +{ + +//Constructor +Bigint::Bigint() +{ + positive = true; + base = 1000000000; + skip = 0; +} +Bigint::Bigint(const Bigint &b) + : number(b.number), + positive(b.positive), + base(b.base), + skip(b.skip) { } +Bigint::Bigint(long long value) +{ + base = 1000000000; + skip = 0; + if (value < 0) { + positive = false; + value *= -1; + } else { + positive = true; + } + + while (value) { + number.push_back((int) (value % base)); + value /= base; + } +} + +Bigint::Bigint(std::string stringInteger) +{ + int size = stringInteger.length(); + + base = 1000000000; + skip = 0; + positive = (stringInteger[0] != '-'); + + while (true) { + if (size <= 0) break; + if (!positive && size <= 1) break; + + int length = 0; + int num = 0; + int prefix = 1; + for (int i(size - 1); i >= 0 && i >= size - 9; --i) { + if (stringInteger[i] < '0' || stringInteger[i] > '9') break; + num += (stringInteger[i] - '0') * prefix; + prefix *= 10; + ++length; + } + number.push_back(num); + size -= length; + } +} + +//Adding +Bigint Bigint::operator+(Bigint const &b) const +{ + Bigint c = *this; + c += b; + + return c; +} + +Bigint &Bigint::operator+=(Bigint const &b) +{ + if (!b.positive) { + return *this -= b; + } + if (!b.positive && positive) { + positive = false; + } + std::vector::iterator + it1 = number.begin(); + std::vector::const_iterator + it2 = b.number.begin(); + int sum = 0; + while (it1 != number.end() || it2 != b.number.end()) { + if (it1 != number.end()) { + sum += *it1; + } else { + number.push_back(0); + it1 = number.end()-1; + } + if (it2 != b.number.end()) { + sum += *it2; + ++it2; + } + *it1 = sum % base; + ++it1; + sum /= base; + } + if (sum) number.push_back(1); + + return *this; +} + +Bigint Bigint::operator+(long long const &b) const +{ + Bigint c = *this; + c += b; + + return c; +} + +Bigint &Bigint::operator+=(long long b) +{ + std::vector::iterator it = number.begin(); + if (skip > number.size()) { + number.insert(number.end(), skip - number.size(), 0); + } + it += skip; + bool initial_flag=true; + while (b || initial_flag) { + initial_flag=false; + if (it != number.end()) { + *it += b % base; + b /= base; + b += *it / base; + *it %= base; + ++it; + } else { + number.push_back(0); + it = number.end() - 1; + } + } + + return *this; +} + +//Subtraction +Bigint Bigint::operator-(Bigint const &b) const +{ + Bigint c = *this; + c -= b; + + return c; +} + +Bigint &Bigint::operator-=(Bigint const &b) +{ + std::vector::iterator + it1 = number.begin(); + std::vector::const_iterator + it2 = b.number.begin(); + int dif = 0; + while (it1 != number.end() || it2 != b.number.end()) { + if (it1 != number.end()) { + dif += *it1; + ++it1; + } + if (it2 != b.number.end()) { + dif -= *it2; + ++it2; + } + if (dif < 0) { + *(it1 - 1) = dif + base; + dif = -1; + } else { + *(it1 - 1) = dif % base; + dif /= base; + } + } + if (dif < 0) positive = false; + + if (number.size() > 1) + { + do + { + it1 = number.end() - 1; + if (*it1 == 0) number.pop_back(); + else break; + } while (number.size() > 1); + } + + return *this; +} + +//Multiplication +Bigint Bigint::operator*(Bigint const &b) +{ + if (b.number.size() == 1) return *this *= b.number[0]; + std::vector::iterator it1; + std::vector::const_iterator it2; + Bigint c("0"); + for (it1 = number.begin(); it1 != number.end(); ++it1) { + for (it2 = b.number.begin(); it2 != b.number.end(); ++it2) { + c.skip = (unsigned int) (it1 - number.begin()) + (it2 - b.number.begin()); //TODO + c += (long long) (*it1) * (*it2); + } + } + c.skip = 0; + + return c; +} + +Bigint &Bigint::operator*=(Bigint const &b) +{ + *this = *this * b; + + return *this; +} + +Bigint Bigint::operator*(long long const &b) +{ + Bigint c = *this; + c *= b; + + return c; +} + +Bigint &Bigint::operator*=(int const &b) +{ + std::vector::iterator it = number.begin(); + long long sum = 0; + while (it != number.end()) { + sum += (long long) (*it) * b; + *it = (int) (sum % base); + sum /= base; + ++it; + } + if (sum) number.push_back((int) sum); + + return *this; +} + +bool Bigint::is_even(){ + if(number.size()==1){ + int x = number[0]; + if(x%2 == 0) + return true; + else + return false; + } + + else if(number.size()>1){ + int x = *(number.begin()); + if(x%2 == 0) + return true; + else + return false; + } + +} + + +Bigint Bigint::sub_number(Bigint &p, Bigint &q){ + + std::string tmpx0, tmpx1, tmpx3; + long window_size = q.digits(); + int last_i_iterator; + std::vector::iterator i=p.number.end()-1; + + if(window_size>p.digits()) + window_size=p.digits(); + + + while(i>=p.number.begin() && window_size>0){ + + tmpx0 = to_string(*i); + int ssss = tmpx0.size(); + if(i!=p.number.end()-1 && ssss<9){ + tmpx0 = std::string(9-ssss,'0') + tmpx0; + } + + if(window_size - ssss < 0){ + tmpx3=tmpx0; + tmpx0=""; + for(int i=0;i=p.number.begin()){ + if(tmpx3.size()!=0){ + window_size++; + tmpx0 = tmpx3[last_i_iterator+1]; + tmpx1 = tmpx1 + tmpx0; + c=tmpx1; + } + else{ + window_size++; + tmpx0 = to_string(*i); + if(i!=p.number.end()-1 && tmpx0.size()<9){ + tmpx0 = std::string(9-tmpx0.size(),'0') + tmpx0; + } + tmpx0 = tmpx0[0]; + tmpx1 = tmpx1 + tmpx0; + c=tmpx1; + } + + } + + return c; +} +//Division + +std::vector Bigint::divide(Bigint q){ + + /*Algorithm used is "Double division algorithm"*/ + + Bigint p = *this; + std::vector answer; + int look_up_table_size=4; + std::vector look_up(look_up_table_size); + bool done_flag=false ; + Bigint tmp_quotient, sum_quotient, tmpx1, tmpx2; + + Bigint zero("0"); + + if(q==zero || q == 0){ + throw "Dividing by zero!"; + } + + bool this_sign = this -> positive; + bool q_sign = q.positive; + + p.positive = true; + q.positive = true; + + + look_up[0]=q; + look_up[1]=q*2; + look_up[2]=q*4; + look_up[3]=q*8; + + + while(true){ + + Bigint sub_p=sub_number(p, q); // cut a portion from the dividened equal in size with the divisor + + for(int i=0;i=p.digits()){ + done_flag=true; + break; + } + } + else if(sub_p==look_up[i] || (sub_p>look_up[i] && i==look_up_table_size-1)){ + tmpx1=look_up[i]; + tmp_quotient= std::pow(2,i); + break; + } + } + + if(done_flag){ + answer.push_back(sum_quotient); + answer.push_back(sub_p); + break; + } + + std::string temppp(p.digits()-(sub_p.digits()),'0'); + temppp="1"+temppp; + tmpx2=temppp; + + if(sum_quotient.digits()==0) + sum_quotient=tmp_quotient*tmpx2; + else + sum_quotient=sum_quotient+(tmp_quotient*tmpx2); + + tmpx1=tmpx1*tmpx2; + p=p-tmpx1; + + } + + if(this_sign == false && q_sign == false){ + answer[0].positive = true; + } + + else if(this_sign == false || q_sign == false){ + if( this -> is_even() && q.is_even()) + answer[0].positive = false; + else{ + answer[0] = answer[0] + Bigint("1"); + answer[0].positive = false; + } + } + + else{ + answer[0].positive = true; + } + + return answer; + +} + +std::vector Bigint::operator/(Bigint q){ + try{ + return divide(q); + } + catch(const char* msg){ + std::cerr << msg << std::endl; + std::terminate(); + } + + +} + + +//Power + +Bigint Bigint::pow(int const &power, std::map &lookup) +{ + if (power == 1) return *this; + if (lookup.count(power)) return lookup[power]; + + int closestPower = 1; + while (closestPower < power) closestPower <<= 1; + closestPower >>= 1; + + if (power == closestPower) lookup[power] = pow(power / 2, lookup) * pow(power / 2, lookup); + else lookup[power] = pow(closestPower, lookup) * pow(power - closestPower, lookup); + + return lookup[power]; +} + +Bigint &Bigint::pow(int const &power) +{ + std::map lookup; + if (power % 2 == 0 && !positive) { + positive = true; + } + *this = pow(power, lookup); + + return *this; +} + +//Compare +int Bigint::compare(const Bigint &a) const //0 this == a || -1 this < a || 1 this > a +{ + if (positive && !a.positive) return 1; + if (!positive && a.positive) return -1; + + int check = 1; + if (!positive && !a.positive) check = -1; + + if (number.size() < a.number.size()) return -1 * check; + if (number.size() > a.number.size()) return check; + for (size_t i(number.size()); i > 0; --i) { + if (number[i-1] < a.number[i-1]) return -1 * check; + if (number[i-1] > a.number[i-1]) return check; + } + + return 0; // == +} + +bool Bigint::operator<(Bigint const &b) const +{ + return compare(b) == -1; +} + +bool Bigint::operator<=(const Bigint &b) const +{ + int compared = compare(b); + + return compared == 0 || compared == -1; +} + +bool Bigint::operator>(const Bigint &b) const +{ + return compare(b) == 1; +} + +bool Bigint::operator>=(const Bigint &b) const +{ + int compared = compare(b); + + return compared == 0 || compared == 1; +} + +bool Bigint::operator==(Bigint const &b) const +{ + return compare(b) == 0; +} + +//Allocation +Bigint Bigint::operator=(const long long &a) +{ + number.clear(); + long long t = a; + do { + number.push_back((int) (t % base)); + t /= base; + } while (t != 0); + + return *this; +} + +//Access +int Bigint::operator[](int const &b) +{ + return to_string(*this)[b] - '0'; +} + +//Trivia +int Bigint::digits() const +{ + int segments = number.size(); + + if (segments == 0) return 0; + + int digits = 9 * (segments - 1); + digits += segment_length(number.back()); + + return digits; +} + +int Bigint::trailing_zeros() const +{ + if (number.empty() || (number.size() == 1 && number[0] == 0)) return 1; + + int zeros = 0; + std::vector::const_iterator it = number.begin(); + if (number.size() > 1) { + for (; it != number.end() - 1 && *it == 0; ++it) { + zeros += 9; + } + } + int a = *it; + while (a % 10 == 0 && a) { + ++zeros; + a /= 10; + } + + return zeros; +} + +//Helpers +void Bigint::clear() +{ + number.clear(); + positive = true; + skip = 0; +} + +Bigint &Bigint::abs() +{ + positive = true; + + return *this; +} + +//Input&Output +std::ostream &operator<<(std::ostream &out, Bigint a) +{ + while (a.number.size() && a.number.back() == 0) a.number.pop_back(); + + if (!a.number.size()) return out << 0; + if (!a.positive) out << '-'; + + std::vector::const_reverse_iterator it = a.number.rbegin(); + + out << *it; + if (it != a.number.rend()) ++it; + for (; it != a.number.rend(); ++it) { + for (int i(0), len = a.segment_length(*it); i < 9 - len; ++i) out << '0'; + if (*it) out << *it; + } + + return out; +} + + +std::istream &operator>>(std::istream &in, Bigint &a) +{ + std::string str; + in >> str; + + a = str; + + return in; +} + +int Bigint::segment_length(int segment) const +{ + int length = 0; + while (segment) { + segment /= 10; + ++length; + } + + return length; +} + +Bigint abs(Bigint value) +{ + return value.abs(); +} + +std::string to_string(Bigint value) +{ + std::ostringstream stream; + stream << value; + + return stream.str(); +} + +Bigint factorial(int n) +{ + Bigint result = 1; + if (n % 2) { + result = n; + --n; + } + int last = 0; + for (; n >= 2; n -= 2) { + result *= n + last; + last += n; + } + + return result; +} + +} From 35a39767071ebdcc31825a00211ad7652f908460 Mon Sep 17 00:00:00 2001 From: mahmoudrizk Date: Mon, 13 Mar 2017 15:59:02 +0200 Subject: [PATCH 7/7] fixing bug in Algorithm --- src/bigint.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/bigint.cpp b/src/bigint.cpp index d268ea4..0b8b138 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -397,12 +397,7 @@ std::vector Bigint::divide(Bigint q){ } else if(this_sign == false || q_sign == false){ - if( this -> is_even() && q.is_even()) - answer[0].positive = false; - else{ - answer[0] = answer[0] + Bigint("1"); - answer[0].positive = false; - } + answer[0].positive = false; } else{