I'm learning Data Structures from a book named "Data Structures using C " by D.S. Malik. I am currently solving the below written programming exercise:
In C , the largest int value is 2147483647. So an integer larger than this cannot be stored and processed as an integer. Similarly, if the sum or product of two positive integers is greater than 2147483647, the result will be incorrect. One way to store and manipulate large integers is to store each individual digit of the number in an array. Design the class largeIntegers so that an object of this class can store an integer up to 100 digits long. Overload the operators and – to add and subtract, respectively, the values of two objects of this class. (In the Programming Exercises in Chapter 3, we will overload the multiplication operator.) Overload the assignment operator to copy the value of a large integer into another large integer. Overload the stream extraction and insertion operators for easy input and output. Your program must contain appropriate constructors to initialize objects of the class largeIntegers. (Hint: Read numbers as strings and store the digits of the number in the reverse order. Add instance variables to store the number of digits and the sign of the number.)
And below is my code for the above:
#include <bits/stdc .h>
using namespace std;
class largeIntegers {
private:
/* data */
int num[100] = {0};
int digits;
bool isPositive;
public:
friend istream &operator>>(istream &, largeIntegers &);
largeIntegers &operator (largeIntegers &);
void getLargeInteger(void);
void setLargeInteger(string);
void print(void);
largeIntegers();
largeIntegers(string);
};
int main() {
largeIntegers num1;
cin >> num1;
largeIntegers num2;
num2 = num1;
cin >> num1;
largeIntegers num3;
num3 = num1 num2;
num3.print();
return 0;
}
largeIntegers &largeIntegers::operator (largeIntegers &integer) {
largeIntegers temp;
int remainder = 0;
int digi = max(digits, integer.digits);
temp.digits = digi;
for (int i = 0; i < digi; i ) {
temp.num[i] = (remainder num[i] integer.num[i]) % 10;
remainder = (remainder num[i] integer.num[i]) / 10;
}
if (remainder) {
temp.num[digi] = remainder;
temp.digits ;
}
return temp;
}
largeIntegers::largeIntegers(string n) { setLargeInteger(n); }
largeIntegers::largeIntegers() {
isPositive = true;
digits = 0;
}
void largeIntegers::setLargeInteger(string n) {
int start = 0;
if (n[0] == '-') {
isPositive = false;
start = 1;
}
digits = 0;
for (int i = n.length() - 1; i >= start; i--) {
num[digits] = int(n[i]) - int('0');
digits ;
}
}
void largeIntegers::getLargeInteger(void) {
cout << "Enter a large integer:\n";
string n;
cin >> n;
setLargeInteger(n);
}
istream &operator>>(istream &isObject, largeIntegers &largeInt) {
string num;
isObject >> num;
largeInt.setLargeInteger(num);
return isObject;
}
void largeIntegers::print(void) {
if (!isPositive)
cout << "-";
for (int i = digits - 1; i >= 0; i--) {
cout << num[i];
}
cout << endl;
}
But my code is not working for the addition operation. It is giving Segmentation fault (core dumped) error. Can someone explain what's the problem and how to fix it?
CodePudding user response:
The problem is that your overloaded operator
was returning a reference to a local variable. To solve this, you can instead use the following version of operator
:
//return by value
largeIntegers operator (const largeIntegers &lhs, const largeIntegers &integer)
{
largeIntegers temp;
int remainder = 0;
int digi = max(lhs.digits, integer.digits);
temp.digits = digi;
for (int i = 0; i < digi; i ) {
temp.num[i] = (remainder lhs.num[i] integer.num[i]) % 10;
remainder = (remainder lhs.num[i] integer.num[i]) / 10;
}
if (remainder) {
temp.num[digi] = remainder;
temp.digits ;
}
return temp;
}
For the above to work make operator
a friend by adding a friend declaration as follows inside the class:
friend largeIntegers operator (const largeIntegers &lhs, const largeIntegers &rhs);
The complete working program that uses the above shown modification can be seen here and is given below:
#include <bits/stdc .h>
using namespace std;
class largeIntegers {
private:
/* data */
int num[100] = {0};
int digits;
bool isPositive;
public:
friend istream &operator>>(istream &, largeIntegers &);
//i have added this friend declaration
friend largeIntegers operator (const largeIntegers &lhs, const largeIntegers &rhs);
void getLargeInteger(void);
void setLargeInteger(string);
void print(void);
largeIntegers();
largeIntegers(string);
};
int main() {
largeIntegers num1;
cin >> num1;
largeIntegers num2;
num2 = num1;
cin >> num1;
largeIntegers num3;
num3 = num1 num2;
num3.print();
return 0;
}
//i have modified the operator as shown below
largeIntegers operator (const largeIntegers &lhs, const largeIntegers &integer)
{
largeIntegers temp;
int remainder = 0;
int digi = max(lhs.digits, integer.digits);
temp.digits = digi;
for (int i = 0; i < digi; i ) {
temp.num[i] = (remainder lhs.num[i] integer.num[i]) % 10;
remainder = (remainder lhs.num[i] integer.num[i]) / 10;
}
if (remainder) {
temp.num[digi] = remainder;
temp.digits ;
}
return temp;
}
largeIntegers::largeIntegers(string n) { setLargeInteger(n); }
largeIntegers::largeIntegers() {
isPositive = true;
digits = 0;
}
void largeIntegers::setLargeInteger(string n) {
int start = 0;
if (n[0] == '-') {
isPositive = false;
start = 1;
}
digits = 0;
for (int i = n.length() - 1; i >= start; i--) {
num[digits] = int(n[i]) - int('0');
digits ;
}
}
void largeIntegers::getLargeInteger(void) {
cout << "Enter a large integer:\n";
string n;
cin >> n;
setLargeInteger(n);
}
istream &operator>>(istream &isObject, largeIntegers &largeInt) {
string num;
isObject >> num;
largeInt.setLargeInteger(num);
return isObject;
}
void largeIntegers::print(void) {
if (!isPositive)
cout << "-";
for (int i = digits - 1; i >= 0; i--) {
cout << num[i];
}
cout << endl;
}
See the comments in the above code to check the modifications i made