Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //============================================================================
- // Name : BigInteger.cpp
- // Author : Oskar Pawica
- // Version : 1.0
- // Copyright : Your copyright notice
- // Description : BigInteger in C++, Ansi-style
- //============================================================================
- #include <iostream>
- #include <cmath>
- #include <algorithm>
- #include <cstdlib>
- #include <stdio.h>
- #include <string.h>
- #include <limits>
- using namespace std;
- class Exception {
- std::string name;
- public:
- Exception (std::string n) : name(n){}
- virtual ~Exception() {}
- virtual std::string get_name () { return name; }
- };
- class DivBy0Exception : public Exception {
- public:
- DivBy0Exception () : Exception("Nie mozna dzielic przez 0!") {}
- virtual ~DivBy0Exception () {}
- };
- class BigInteger
- {
- private:
- long size;
- char* e;
- BigInteger multiply(const char& c, const unsigned int& m) const {
- if(c=='0' or e[0] == '0') {
- BigInteger temp_null('0');
- return temp_null;
- }
- BigInteger temp(this->size+1+m, true);
- temp.e = new char[this->size+1+m];
- memcpy(temp.e+1+m, this->e+1, size-1);
- temp.e[0] = '+';
- for(unsigned int j = 1; j<=m; ++j) {
- temp.e[j] = '0';
- }
- temp.e[temp.size-1] = '0';
- unsigned int r=0, temp_res;
- for(unsigned int i = 1; i<size; ++i) {
- temp_res = (e[i]-48)*(c-48)+r;
- temp.e[i+m] = (temp_res%10)+48;
- r = temp_res/10;
- }
- if(r == 0)
- temp = temp.check_zeros();
- else
- temp.e[temp.size-1] = r+48;
- temp = temp.check_zeros();
- return temp;
- }
- public:
- BigInteger() : size(0), e(NULL) {}
- BigInteger(long a){
- size = 1;
- if(a == 0)
- {
- e = new char[size];
- *e = '0';
- }
- else
- {
- size += numberOfDigits(abs(a));
- e = new char [size];
- if(a > 0)
- *e = '+';
- else {
- *e = '-';
- a = -a;
- }
- int i = 1;
- while(a >= 1)
- {
- sprintf(e+i, "%ld", a%10);
- a/=10;
- i++;
- }
- }
- }
- BigInteger(long ssize, bool): size(ssize), e(NULL) {}
- BigInteger(const char* a){
- size = 1;
- if(*a == '0'){
- e = new char [size];
- *e = '0';
- }
- else
- {
- char j;
- int i = 0;
- if(*a == '+' or *a == '-') {
- j = *a;
- i++;
- }
- else {
- j = '+';
- }
- while(*(a+i)>=48 and *(a+i)<=57) {
- size++;
- i++;
- }
- e = new char [size];
- *e = j;
- i--;
- int k = 1;
- while(*(a+i)>=48 and *(a+i)<=57) {
- *(e+k) = *(a+i);
- i--;
- k++;
- }
- }
- }
- virtual ~BigInteger()
- {
- delete [] e;
- }
- BigInteger (const BigInteger &b):size(b.size)
- {
- e = new char[b.size];
- strcpy(e, b.e);
- }
- BigInteger &operator =(const BigInteger &b)
- {
- size = b.size;
- if (e!=NULL)
- delete [] e;
- e = new char [size];
- memcpy(e,b.e,size*sizeof(char));
- return *this;
- }
- BigInteger &operator =(long a)
- {
- size = 1;
- if (e!=NULL)
- delete [] e;
- if(a == 0)
- {
- e = new char[size];
- *e = '0';
- }
- else
- {
- size += numberOfDigits(abs(a));
- e = new char [size];
- if(a > 0)
- *e = '+';
- else {
- *e = '-';
- a = -a;
- }
- int i = 1;
- while(a >= 1)
- {
- sprintf(e+i, "%ld", a%10);
- a/=10;
- i++;
- }
- }
- return *this;
- }
- bool operator ==(const BigInteger &b) const
- {
- if(this->size != b.size)
- return 0;
- for (int i = 0; i < size; i++)
- if(this->e[i]!=b.e[i])
- return 0;
- return 1;
- }
- bool operator !=(const BigInteger &b) const
- {
- if(this->size != b.size)
- return 1;
- for (int i = 0; i < size; i++)
- if(this->e[i]!=b.e[i])
- return 1;
- return 0;
- }
- bool operator >(const BigInteger &b) const
- {
- if(*this == b)
- return 0;
- if(this->e[0]!=b.e[0]) {
- if(this->e[0] == '+')
- return 1;
- else
- return 0;
- }
- if(this->size > b.size)
- if(this->e[0] == '+')
- return 1;
- else
- return 0;
- else if (this->size < b.size)
- if(this->e[0] == '+')
- return 0;
- else
- return 1;
- else
- {
- bool left = false;
- int s = size-1;
- for (int i = s; i > 0; --i) {
- if (this->e[i] == b.e[i])
- continue;
- if(this->e[i] > b.e[i])
- {
- left = true;
- break;
- }
- else
- break;
- }
- if(left)
- {
- if(this->e[0] == '+')
- return 1;
- else
- return 0;
- }
- else
- {
- if(this->e[0] == '+')
- return 0;
- else
- return 1;
- }
- }
- }
- bool operator <(const BigInteger &b) const
- {
- return b > (*this);
- }
- bool operator >=(const BigInteger &b) const
- {
- if(*this==b)
- return 1;
- if(*this>b)
- return 1;
- return 0;
- }
- bool operator <=(const BigInteger &b) const
- {
- if(*this==b) {
- return 1;
- }
- if(*this<b){
- return 1;}
- return 0;
- }
- BigInteger operator +(const BigInteger &b) const
- {
- if(e[0] == '0')
- return b;
- if(b.e[0] == '0')
- return *this;
- if(e[0] == '-' and b.e[0] != '-')
- return b - (-(*this));
- if(b.e[0] == '-' and e[0] != '-')
- return (*this)-(-b);
- if(size<b.size)
- return b+(*this);
- BigInteger temp(this->size, true);
- temp.e = new char [this->size];
- temp.e[0] = '+';
- unsigned int i = 1;
- char temp_c;
- bool t = false;
- while (i<strlen(b.e)) {
- temp_c = this->e[i]+b.e[i]-48;
- if(t) {
- temp_c+=1;
- t = false;
- }
- if(temp_c-48 >= 10) {
- temp_c = (temp_c-48)%10+48;
- t = true;
- }
- temp.e[i] = temp_c;
- ++i;
- }
- if (i<strlen(this->e)) {
- memcpy(temp.e+i, e+i, strlen(this->e)-i);
- if(t) {
- temp.e[i]+=1;
- if(temp.e[i]>57) {
- temp.e[i] = '0';
- }
- else
- t = false;
- }
- }
- if(b.e[0] == '-' and e[0] == '-') {
- temp.e[0] = '-';
- temp = temp.check_zeros();
- }
- if(t) {
- BigInteger temp2(temp.size+1, true);
- temp2.e = new char [temp.size+1];
- memcpy(temp2.e, temp.e, strlen(temp.e));
- temp2.e[size] = '1';
- return temp2;
- }
- else
- return temp;
- }
- BigInteger operator +(const long &a) const {
- BigInteger temp(a);
- return *this+temp;
- }
- BigInteger &operator +=(const BigInteger &b)
- {
- *this = *this+b;
- return *this;
- }
- BigInteger &operator *=(const BigInteger &b)
- {
- *this = *this*b;
- return *this;
- }
- BigInteger &operator /=(const BigInteger &b)
- {
- *this = *this/b;
- return *this;
- }
- BigInteger &operator %=(const BigInteger &b)
- {
- *this = *this%b;
- return *this;
- }
- BigInteger &operator -=(BigInteger &b)
- {
- *this = *this-b;
- return *this;
- }
- BigInteger &operator +=(const long &b)
- {
- *this = *this+b;
- return *this;
- }
- BigInteger &operator *=(const long &b)
- {
- *this = *this*b;
- return *this;
- }
- BigInteger &operator /=(const long &b)
- {
- *this = *this/b;
- return *this;
- }
- BigInteger &operator %=(const long &b)
- {
- *this = *this%b;
- return *this;
- }
- BigInteger &operator -=(const long &b)
- {
- *this = *this-b;
- return *this;
- }
- BigInteger operator -(const BigInteger &b) const
- {
- if (this->e[0] == '0')
- return -b;
- if (b.e[0] == '0')
- return *this;
- if (*this == b)
- {
- BigInteger temp_null('0');
- return temp_null;
- }
- if(b.e[0] == '-' and e[0] != '-')
- return *this+(-b);
- if(e[0] == '-' and b.e[0] != '-')
- return (*this)+(-b);
- if(e[0] == '-' and b.e[0] == '-')
- return (-b)+(*this);
- BigInteger temp;
- if(*this < b) {
- temp = b - *this;
- return -temp;
- }
- temp = *this;
- char temp_c;
- unsigned int i;
- for(i = 1; i < b.size; ++i) {
- temp_c = e[i]-b.e[i]+48;
- if (temp_c < 48) {
- temp_c+=10;
- --e[i+1];
- for(unsigned int k = i+1; k < this->size-1; ++k) {
- if(e[k]>='0')
- break;
- else {
- e[k] = '9';
- --e[k+1];
- }
- }
- }
- temp.e[i] = temp_c;
- }
- while(i<size) {
- temp.e[i] = e[i];
- ++i;
- }
- temp = temp.check_zeros();
- return temp;
- }
- BigInteger operator/(const BigInteger& b) const {
- if(b.e[0] == '0')
- throw DivBy0Exception();
- bool negative = true;
- if(e[0] == b.e[0])
- negative = false;
- BigInteger origin(*this);
- origin.e[0] = '+';
- b.e[0] = '+';
- BigInteger temp_r(RAND_MAX);
- if (temp_r*b<*this) {
- return over_rand(b, negative);
- }
- long long temp_l = rand();
- BigInteger temp(temp_l);
- bool one, two;
- while(1) {
- temp = temp_l;
- if(temp_l > RAND_MAX)
- return over_rand(b, negative);
- one = b*temp <= origin;
- two = b*(temp+1) > origin;
- if(one and two)
- break;
- if(!one) {
- temp_l = rand()%temp_l;
- continue;
- }
- if(one) {
- temp_l = temp_l+rand();
- continue;
- }
- }
- if(negative)
- return -temp;
- else return temp;
- }
- BigInteger over_rand(const BigInteger& b, const bool& negative) const {
- BigInteger temp(RAND_MAX);
- bool one, two;
- while(1) {
- one = b*temp <= *this;
- two = b*(temp+1) > *this;
- if(one and two)
- break;
- else
- temp+=1;
- }
- if (negative)
- return -temp;
- return temp;
- }
- BigInteger operator%(const BigInteger& b) const {
- if(b>*this)
- return *this;
- BigInteger temp(*this/b);
- return *this-(temp*b);
- }
- BigInteger operator%(const long& a) const {
- BigInteger temp(a);
- return *this%temp;
- }
- BigInteger operator/(const long& a) const {
- if(a == 0)
- throw DivBy0Exception();
- BigInteger temp(a);
- return *this/temp;
- }
- BigInteger operator*(const BigInteger& b) const {
- if(b.e[0] == '0' or e[0] == '0')
- {
- BigInteger temp_null('0');
- return temp_null;
- }
- if(b.size > this->size)
- return b*(*this);
- bool negative = false;
- if(b.e[0]!=e[0])
- negative = true;
- if(b.e[1] == '1' and b.size==2) {
- if(negative)
- return -(*this);
- else
- return *this;
- }
- else if(e[1] == '1' and size==2) {
- if(negative)
- return -(b);
- else return b;
- }
- BigInteger temp [b.size-1];
- for(unsigned int i = 1; i < b.size; ++i) {
- temp[i-1] = multiply(b.e[i], i-1);
- }
- for(unsigned int i = 1; i < b.size-1; ++i)
- temp[0] = temp[i] + temp[0];
- if(negative)
- temp[0].e[0] = '-';
- return temp[0];
- }
- BigInteger check_zeros() {
- if(e[size-1] == '0') {
- unsigned int zeros = 1;
- for(unsigned int i = size-2; i > 0; --i) {
- if(e[i] == '0')
- ++zeros;
- else
- break;
- }
- BigInteger temp(size-zeros, true);
- temp.e = new char [size-zeros];
- memcpy(temp.e, this->e, strlen(e)-zeros);
- return temp;
- }
- return *this;
- }
- BigInteger operator -(const long &b) const
- {
- BigInteger temp(b);
- return *this-temp;
- }
- BigInteger operator *(const long &b) const
- {
- BigInteger temp(b);
- return *this*temp;
- }
- BigInteger operator ++(int)
- {
- BigInteger temp(*this);
- *this+=1;
- return temp;
- }
- BigInteger &operator ++()
- {
- *this+=1;
- return *this;
- }
- BigInteger operator --(int)
- {
- BigInteger temp(*this);
- *this-=1;
- return temp;
- }
- BigInteger &operator --()
- {
- *this-=1;
- return *this;
- }
- BigInteger operator -() const
- {
- if(e[0]=='0')
- return *this;
- BigInteger temp = *this;
- temp.e[0]=='+' ? temp.e[0] ='-' : temp.e[0] ='+';
- return temp;
- }
- /*
- char &operator [] (const int &b) const
- {
- return e[size-1-b];
- }
- */
- char &operator [] (const int &b) const
- {
- return e[b+1];
- }
- long numberOfDigits(const long& a) const {
- if(a<=9){
- return 1;
- }
- return 1 + numberOfDigits(a/10);
- }
- friend ostream& operator <<(ostream& os, const BigInteger& b);
- friend istream& operator >>(istream& is, BigInteger& b);
- };
- ostream& operator<<(ostream& os, const BigInteger& b)
- {
- if (b.e[0] == '0')
- os << '0';
- else {
- if (b.e[0] == '-')
- os << '-';
- for (int i = b.size-1; i > 0; --i)
- os << b.e[i];
- }
- return os;
- }
- istream& operator>>(istream& is, BigInteger& b)
- {
- string s;
- is >> s;
- const char * temp = s.c_str();
- BigInteger b_temp(temp);
- b = b_temp;
- return is;
- }
- BigInteger operator +(const long& a, const BigInteger& b)
- {
- return b+a;
- }
- BigInteger operator -(const long& a, const BigInteger& b)
- {
- BigInteger temp(a);
- return temp-b;
- }
- BigInteger operator *(const long& a, const BigInteger& b)
- {
- BigInteger temp(a);
- return temp*b;
- }
- BigInteger operator /(const long& a, const BigInteger& b)
- {
- BigInteger temp(a);
- return temp/b;
- }
- BigInteger operator %(const long& a, const BigInteger& b)
- {
- BigInteger temp(a);
- return temp%b;
- }
- int main() {
- {
- try {
- srand(time(NULL));
- BigInteger test(5720);
- BigInteger test2(715);
- std::cout<<test2<<std::endl;
- std::cout<<(test<test2)<<std::endl;
- std::cout<<test<<std::endl;
- test = test+test2;;
- std::cout<<test<<std::endl;
- std::cout<<"----"<<std::endl;
- long a = -1;
- char b[] = "-145";
- BigInteger x = a;
- BigInteger y = b;
- std::cout<<x<<" "<<y<<std::endl;
- std::cout<<y<<std::endl;
- BigInteger z = x+(y++);
- std::cout<<y<<std::endl;
- std::cout<<z<<std::endl;
- z = z+100;
- std::cout<<z+z<<std::endl;
- std::cout<<y<<std::endl;
- std::cout<<2+y<<std::endl;
- std::cout<<y<<std::endl;
- std::cout<<x<<std::endl;
- y = x-y;
- std::cout<<y<<std::endl;
- std::cout<<y*45<<std::endl;
- std::cout<<y/45<<std::endl;
- } catch (Exception& e) {
- std::cerr<<"Wystapil blad. "<<e.get_name()<<std::endl;
- std::abort();
- }
- }
- std::cout<<"End."<<std::endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement