├── BigInteger.cpp ├── BigInteger.h ├── BigIntegerSingleFile.cpp ├── Makefile ├── README.md └── tests.cpp /BigInteger.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BigInteger Class, performs basic arithmetic operations of very large integers. 3 | * Copyright (C) 2011 Mahmoud Mechehoul 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include "BigInteger.h" 22 | 23 | using namespace std; 24 | 25 | BigInteger::BigInteger(unsigned int integer) { 26 | setInteger(integer); 27 | } 28 | 29 | BigInteger::BigInteger(string integer) { 30 | for (int i = 0; i < (int)integer.size() && integer[i] >= '0' && integer[i] <= '9'; i++) { 31 | this->integer += integer[i]; 32 | } 33 | 34 | if (this->integer.size() == 0) { 35 | this->integer = "0"; 36 | } else { 37 | this->integer = integer.substr(getTrimIndex(integer)); 38 | } 39 | } 40 | 41 | void BigInteger::setInteger(unsigned int integer) { 42 | if (integer == 0) this->integer = "0"; 43 | 44 | while (integer) { 45 | this->integer = (char)((integer % 10) + '0') + this->integer; 46 | integer /= 10; 47 | } 48 | } 49 | 50 | void BigInteger::setInteger(string integer) { 51 | this->integer = integer; 52 | } 53 | 54 | unsigned int BigInteger::getIntValue() const { 55 | unsigned int ret = 0; 56 | unsigned int biggest = 0xFFFFFFFF; 57 | for (int i = 0; i < (int)integer.size(); i++) { 58 | int unit = integer[i] - '0'; 59 | if (ret > (biggest - unit) / 10.0) return 0; 60 | ret = ret * 10 + unit; 61 | } 62 | return ret; 63 | } 64 | 65 | string BigInteger::toString() const { 66 | return integer; 67 | } 68 | 69 | BigInteger BigInteger::addInteger(const BigInteger& integer_to_add) const { 70 | int a_n = max((int)(integer_to_add.toString().size() - toString().size()), 0); 71 | int b_n = max((int)(toString().size() - integer_to_add.toString().size()), 0); 72 | string a = string(a_n, '0') + toString(); 73 | string b = string(b_n, '0') + integer_to_add.toString(); 74 | 75 | reverse(a.begin(), a.end()); 76 | reverse(b.begin(), b.end()); 77 | 78 | string result; int carry = 0; 79 | 80 | for (int i = 0; i < (int)a.size(); i++) { 81 | int sum = (a[i] - '0') + (b[i] - '0') + carry; 82 | result += ((char)(sum % 10 + '0')); 83 | carry = sum / 10; 84 | } 85 | 86 | if (carry != 0) result += ((char)(carry + '0')); 87 | 88 | reverse(result.begin(), result.end()); 89 | 90 | return BigInteger(result.substr(getTrimIndex(result))); 91 | } 92 | 93 | BigInteger BigInteger::addInteger(const string& integer_to_add) const { 94 | return addInteger(BigInteger(integer_to_add)); 95 | } 96 | 97 | BigInteger BigInteger::multiplyInteger(const BigInteger& integer_to_multiply) const { 98 | string a = integer_to_multiply.toString(); 99 | string b = toString(); 100 | 101 | reverse(a.begin(), a.end()); 102 | reverse(b.begin(), b.end()); 103 | 104 | BigInteger ret("0"); 105 | 106 | for (int i = 0; i < (int)a.size(); i++) { 107 | int carry = 0; string tmp = string(i, '0'); 108 | 109 | for (int j = 0; j < (int)b.size(); j++) { 110 | int mul = (a[i] - '0') * (b[j] - '0') + carry; 111 | tmp += ((char)(mul % 10 + '0')); 112 | carry = mul / 10; 113 | } 114 | 115 | if (carry != 0) tmp += (carry + '0'); 116 | 117 | reverse(tmp.begin(), tmp.end()); 118 | 119 | ret = ret.addInteger(tmp.substr(getTrimIndex(tmp))); 120 | } 121 | 122 | return ret; 123 | } 124 | 125 | BigInteger BigInteger::multiplyInteger(const string& integer_to_multiply) const { 126 | return multiplyInteger(BigInteger(integer_to_multiply)); 127 | } 128 | 129 | size_t BigInteger::getTrimIndex(const string& integer) { 130 | size_t index = 0; 131 | while (integer[index] == '0' && index < integer.size() - 1) index++; 132 | return index; 133 | } 134 | 135 | bool BigInteger::operator==(const BigInteger& integer) const { 136 | return this->integer == integer.toString(); 137 | } 138 | 139 | BigInteger BigInteger::operator+(const BigInteger& integer) const { 140 | return addInteger(integer); 141 | } 142 | 143 | BigInteger BigInteger::operator*(const BigInteger& integer) const { 144 | return multiplyInteger(integer); 145 | } 146 | 147 | ostream& operator<<(ostream& in, BigInteger& integer) { 148 | in << integer.toString(); 149 | 150 | return in; 151 | } 152 | -------------------------------------------------------------------------------- /BigInteger.h: -------------------------------------------------------------------------------- 1 | /* 2 | * BigInteger Class, performs basic arithmetic operations of very large integers. 3 | * Copyright (C) 2011 Mahmoud Mechehoul 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #ifndef BIGINT_H_ 20 | #define BIGINT_H_ 21 | 22 | #include 23 | 24 | using namespace std; 25 | 26 | class BigInteger { 27 | private: 28 | string integer; 29 | public: 30 | /* Constructs a big integer representation of the integer given as an argument */ 31 | BigInteger(unsigned int integer); 32 | 33 | /* Parses the string given as an argument looking for an integer. 34 | * Stops as soon as it finds a non-digit character. 35 | * Trailing zeros will eventually get removed. 36 | */ 37 | BigInteger(string integer); 38 | 39 | /* Constructs a big integer representation of the integer given as an argument 40 | * and assigns it to the internal representation of the big integer. 41 | */ 42 | void setInteger(unsigned int integer); 43 | 44 | /* Parses the string given as an argument looking for an integer and assigns it to 45 | * the internal representation of the big integer. 46 | * Stops as soon as it finds a non-digit character. 47 | * Trailing zeros will eventually get removed. 48 | */ 49 | void setInteger(string integer); 50 | 51 | /* Returns 0 if the value of the internal big integer won't fit in 32 bits. 52 | * Otherwise it returns the integer values. 53 | */ 54 | unsigned int getIntValue() const; 55 | 56 | /* Returns the internal big integer as a string */ 57 | string toString() const; 58 | 59 | /* Adds the big integer given as an argument to the internal big integer 60 | * and returns the result as a string. 61 | */ 62 | BigInteger addInteger(const BigInteger& integer_to_add) const; 63 | 64 | /* Adds the integer represented by the string given as an argument to the internal 65 | * big integer and returns the result as a string. 66 | */ 67 | BigInteger addInteger(const string& integer_to_add) const; 68 | 69 | /* Multiplies the big integer given as an argument by the internal big integer 70 | * and returns the result as a string. 71 | */ 72 | BigInteger multiplyInteger(const BigInteger& integer_to_multiply) const; 73 | 74 | /* Multiplies the integer represented by the string given as an argument by the internal 75 | * big integer and returns the result as a string. 76 | */ 77 | BigInteger multiplyInteger(const string& integer_to_multiply) const; 78 | 79 | /* Returns the index of the first non-zero digit in the string given as an argument. 80 | * This function is used to trim trailing zeros from a string representation of an integer. 81 | * A trimmed version of the string is a substring that starts at the index returned by this 82 | * function. 83 | */ 84 | static size_t getTrimIndex(const string& integer); 85 | 86 | bool operator==(const BigInteger& integer) const; 87 | 88 | BigInteger operator+(const BigInteger& integer) const; 89 | 90 | BigInteger operator*(const BigInteger& integer) const; 91 | 92 | friend ostream& operator<<(ostream& in, BigInteger& integer); 93 | }; 94 | 95 | #endif /* BIGINT_H_ */ 96 | -------------------------------------------------------------------------------- /BigIntegerSingleFile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BigInteger Class, performs basic arithmetic operations of very large integers. 3 | * Copyright (C) 2011 Mahmoud Mechehoul 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | using namespace std; 23 | 24 | /* This is a minimized version of the BigInteger class meant to be 25 | * used for single file development purposes (such as programming contests). 26 | * For a complete documentation on what every method does please refer to 27 | * the class header file 'BigInteger.h'. 28 | */ 29 | class BigInteger { 30 | private: 31 | string integer; 32 | public: 33 | BigInteger(unsigned int integer); 34 | BigInteger(string integer); 35 | void setInteger(unsigned int integer); 36 | void setInteger(string integer); 37 | unsigned int getIntValue() const; 38 | string toString() const; 39 | BigInteger addInteger(const BigInteger& integer_to_add) const; 40 | BigInteger addInteger(const string& integer_to_add) const; 41 | BigInteger multiplyInteger(const BigInteger& integer_to_multiply) const; 42 | BigInteger multiplyInteger(const string& integer_to_multiply) const; 43 | static size_t getTrimIndex(const string& integer); 44 | bool operator==(const BigInteger& integer) const; 45 | BigInteger operator+(const BigInteger& integer) const; 46 | BigInteger operator*(const BigInteger& integer) const; 47 | friend ostream& operator<<(ostream& in, BigInteger& integer); 48 | }; 49 | 50 | int main() { 51 | 52 | // INSERT YOUR CODE HERE 53 | 54 | /* This is a sample code that demonstrates how to use the 55 | * Big Integer arithmetic library. 56 | * 57 | * BigInteger a("35742549198872617291353508656626642567"); 58 | * BigInteger b("1298074214633706835075030044377087"); 59 | * 60 | * BigInteger c = a + b; 61 | * BigInteger d = a * b; 62 | * 63 | * cout << a << " + " << b << " = " << c << endl; 64 | * cout << a << " * " << b << " = " << d << endl; 65 | */ 66 | 67 | return 0; 68 | } 69 | 70 | BigInteger::BigInteger(unsigned int integer) { 71 | setInteger(integer); 72 | } 73 | 74 | BigInteger::BigInteger(string integer) { 75 | for (int i = 0; i < (int)integer.size() && integer[i] >= '0' && integer[i] <= '9'; i++) { 76 | this->integer += integer[i]; 77 | } 78 | 79 | if (this->integer.size() == 0) { 80 | this->integer = "0"; 81 | } else { 82 | this->integer = integer.substr(getTrimIndex(integer)); 83 | } 84 | } 85 | 86 | void BigInteger::setInteger(unsigned int integer) { 87 | if (integer == 0) this->integer = "0"; 88 | 89 | while (integer) { 90 | this->integer = (char)((integer % 10) + '0') + this->integer; 91 | integer /= 10; 92 | } 93 | } 94 | 95 | void BigInteger::setInteger(string integer) { 96 | this->integer = integer; 97 | } 98 | 99 | unsigned int BigInteger::getIntValue() const { 100 | unsigned int ret = 0; 101 | unsigned int biggest = 0xFFFFFFFF; 102 | for (int i = 0; i < (int)integer.size(); i++) { 103 | int unit = integer[i] - '0'; 104 | if (ret > (biggest - unit) / 10.0) return 0; 105 | ret = ret * 10 + unit; 106 | } 107 | return ret; 108 | } 109 | 110 | string BigInteger::toString() const { 111 | return integer; 112 | } 113 | 114 | BigInteger BigInteger::addInteger(const BigInteger& integer_to_add) const { 115 | int a_n = max((int)(integer_to_add.toString().size() - toString().size()), 0); 116 | int b_n = max((int)(toString().size() - integer_to_add.toString().size()), 0); 117 | string a = string(a_n, '0') + toString(); 118 | string b = string(b_n, '0') + integer_to_add.toString(); 119 | 120 | reverse(a.begin(), a.end()); 121 | reverse(b.begin(), b.end()); 122 | 123 | string result; int carry = 0; 124 | 125 | for (int i = 0; i < (int)a.size(); i++) { 126 | int sum = (a[i] - '0') + (b[i] - '0') + carry; 127 | result += ((char)(sum % 10 + '0')); 128 | carry = sum / 10; 129 | } 130 | 131 | if (carry != 0) result += ((char)(carry + '0')); 132 | 133 | reverse(result.begin(), result.end()); 134 | 135 | return BigInteger(result.substr(getTrimIndex(result))); 136 | } 137 | 138 | BigInteger BigInteger::addInteger(const string& integer_to_add) const { 139 | return addInteger(BigInteger(integer_to_add)); 140 | } 141 | 142 | BigInteger BigInteger::multiplyInteger(const BigInteger& integer_to_multiply) const { 143 | string a = integer_to_multiply.toString(); 144 | string b = toString(); 145 | 146 | reverse(a.begin(), a.end()); 147 | reverse(b.begin(), b.end()); 148 | 149 | BigInteger ret("0"); 150 | 151 | for (int i = 0; i < (int)a.size(); i++) { 152 | int carry = 0; string tmp = string(i, '0'); 153 | 154 | for (int j = 0; j < (int)b.size(); j++) { 155 | int mul = (a[i] - '0') * (b[j] - '0') + carry; 156 | tmp += ((char)(mul % 10 + '0')); 157 | carry = mul / 10; 158 | } 159 | 160 | if (carry != 0) tmp += (carry + '0'); 161 | 162 | reverse(tmp.begin(), tmp.end()); 163 | 164 | ret = ret.addInteger(tmp.substr(getTrimIndex(tmp))); 165 | } 166 | 167 | return ret; 168 | } 169 | 170 | BigInteger BigInteger::multiplyInteger(const string& integer_to_multiply) const { 171 | return multiplyInteger(BigInteger(integer_to_multiply)); 172 | } 173 | 174 | size_t BigInteger::getTrimIndex(const string& integer) { 175 | size_t index = 0; 176 | while (integer[index] == '0' && index < integer.size() - 1) index++; 177 | return index; 178 | } 179 | 180 | bool BigInteger::operator==(const BigInteger& integer) const { 181 | return this->integer == integer.toString(); 182 | } 183 | 184 | BigInteger BigInteger::operator+(const BigInteger& integer) const { 185 | return addInteger(integer); 186 | } 187 | 188 | BigInteger BigInteger::operator*(const BigInteger& integer) const { 189 | return multiplyInteger(integer); 190 | } 191 | 192 | ostream& operator<<(ostream& in, BigInteger& integer) { 193 | in << integer.toString(); 194 | 195 | return in; 196 | } 197 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: demo tests 2 | 3 | demo : BigIntegerSingleFile.o 4 | g++ -o demo BigIntegerSingleFile.o 5 | 6 | BigIntegerSingleFile.o : BigIntegerSingleFile.cpp 7 | g++ -c BigIntegerSingleFile.cpp 8 | 9 | tests : BigInteger.o tests.o 10 | g++ -o run_tests BigInteger.o tests.o 11 | 12 | BigInteger.o : BigInteger.cpp 13 | g++ -c BigInteger.cpp 14 | 15 | tests.o : tests.cpp 16 | g++ -c tests.cpp 17 | 18 | clean: 19 | rm -rf *.o tests demo -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BigIntegerCPP, a C++ Big Integer Library 2 | ---------------------------------------- 3 | 4 | BigIntegerCPP is a C++ library that performs basic arithmetic operations on large intergers which would not normally fit in a 64 bits integer. 5 | 6 | ### Status: 7 | 8 | At the present moment the library supports Big Integer Addition and Multiplication. 9 | In the future, I am planning to implement the Substraction and Division operations. 10 | Feel free to fork the project and add your own code. 11 | 12 | ### Test: 13 | 14 | To test run the following commands 15 | 16 | make tests 17 | ./run_tests 18 | 19 | ### Usage: 20 | 21 | // Create two big integers 22 | BigInteger a("35742549198872617291353508656626642567"); 23 | BigInteger b("1298074214633706835075030044377087"); 24 | 25 | // Perfom the addition and multiplication of the big integers 26 | // and store the result in new objects 27 | BigInteger c = a + b; 28 | BigInteger d = a * b; 29 | 30 | // Display the operands (Big Integers) and opration result (another Big Integer) 31 | cout << a << " + " << b << " = " << c << endl; 32 | cout << a << " * " << b << " = " << d << endl; 33 | 34 | ### Run Demo: 35 | 36 | I have included a single file implementation for your convenience. 37 | To run the demo uncomment the code in 'BigIntegerSingleFile' then run the following commands 38 | 39 | make demo 40 | ./demo 41 | 42 | ### Bugs: 43 | 44 | Please report any bugs you found in the library by email to mahmoud at devgator dot com. 45 | I will appreciate it if you include the test case where the library failed. 46 | 47 | ### Author: 48 | 49 | [Mahmoud Mechehoul](http://mahmoud.devgator.com) -------------------------------------------------------------------------------- /tests.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * BigInteger Class, performs basic arithmetic operations of very large integers. 3 | * Copyright (C) 2011 Mahmoud Mechehoul 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "BigInteger.h" 24 | 25 | using namespace std; 26 | 27 | #define ADD 0 28 | #define MUL 1 29 | 30 | void big_integer_class_tester(); 31 | 32 | void small_integer_tester(int tests, int operation); 33 | 34 | void big_integer_addition_tester(); 35 | 36 | void big_integer_multiplication_tester(); 37 | 38 | int main() { 39 | big_integer_class_tester(); 40 | small_integer_tester(1000, ADD); 41 | small_integer_tester(1000, MUL); 42 | big_integer_addition_tester(); 43 | big_integer_multiplication_tester(); 44 | 45 | return 0; 46 | } 47 | 48 | void big_integer_class_tester() { 49 | cout << "Big Integer Class Tester" << endl; 50 | 51 | BigInteger big_int_0("0"); 52 | BigInteger big_int_0s("00000000"); 53 | BigInteger big_int_1_digit(9); 54 | BigInteger big_int_10(10); 55 | BigInteger big_int_1000(1000); 56 | BigInteger big_int(0xFFFFFFFF); 57 | BigInteger very_big_int("7" + string(50, '9') + "8"); 58 | BigInteger overflow("4294967296"); 59 | 60 | cout << "Zero: " << big_int_0.toString() << endl; 61 | cout << "Zeros: " << big_int_0s.toString() << endl; 62 | cout << "Single digit: " << big_int_1_digit.toString() << endl; 63 | cout << "Ten: " << big_int_10.toString() << endl; 64 | cout << "Thousand: " << big_int_1000.toString() << endl; 65 | cout << "Big integer: " << big_int.getIntValue() << endl; 66 | cout << "Real big integer: " << very_big_int.toString() << endl; 67 | cout << "Overflow: " << overflow.getIntValue() << endl; 68 | cout << endl; 69 | } 70 | 71 | /* operation: 0 for addition, 1 for multiplication */ 72 | void small_integer_tester(int tests, int operation) { 73 | cout << "Small Integer " << (operation == 0 ? "Addition" : "Multiplication") << " Tests" << endl; 74 | srand(time(NULL)); 75 | int failed = 0; 76 | for (int i = 0; i < tests; i++) { 77 | int c = floor(sqrt(0xFFFFFF)); 78 | int a = rand() % c, b = rand() % c; 79 | BigInteger big_a(a), big_b(b); 80 | bool fail; 81 | if (operation == 0) { 82 | fail = BigInteger(a + b).toString() != (big_a + big_b).toString(); 83 | } else { 84 | fail = BigInteger(a * b).toString() != (big_a * big_b).toString(); 85 | } 86 | failed += (fail ? 1 : 0); 87 | } 88 | cout << failed << " tests failed from " << tests << endl << endl; 89 | } 90 | 91 | void big_integer_addition_tester() { 92 | cout << "Big Integer Addition Tests" << endl; 93 | 94 | BigInteger small("99"); 95 | BigInteger big(string(10, '9')); 96 | BigInteger very_big(string(30, '9')); 97 | BigInteger small_big = BigInteger("10000000098"); 98 | BigInteger small_very_big = BigInteger("1000000000000000000000000000098"); 99 | BigInteger very_big_twice = BigInteger("1999999999999999999999999999998"); 100 | 101 | cout << "Small + Big: " << (small + big == big + small) << " " << (big + small == small_big) << endl; 102 | 103 | cout << "Small + Very Big: " << (small + very_big == very_big + small) << " " << (very_big + small == small_very_big) << endl; 104 | 105 | cout << "Very Big + Very Big: " << (very_big + very_big == very_big_twice) << endl; 106 | 107 | cout << endl; 108 | } 109 | 110 | void big_integer_multiplication_tester() { 111 | cout << "Big Integer Multiplication Tests" << endl; 112 | 113 | BigInteger small("99"); 114 | BigInteger big(string(10, '9')); 115 | BigInteger very_big(string(30, '9')); 116 | BigInteger small_big("989999999901"); 117 | BigInteger small_very_big("98999999999999999999999999999901"); 118 | BigInteger very_big_twice("999999999999999999999999999998000000000000000000000000000001"); 119 | 120 | cout << "Small * Big: " << (small * big == big * small) << " " << (big * small == small_big) << endl; 121 | 122 | cout << "Small * Very Big: " << (small * very_big == very_big * small) << " " << (very_big * small == small_very_big) << endl; 123 | 124 | cout << "Very Big * Very Big: " << (very_big * very_big == very_big_twice) << endl; 125 | 126 | cout << endl; 127 | } 128 | --------------------------------------------------------------------------------