├── 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 |
--------------------------------------------------------------------------------