Using vector in C++ to calculate big integer - c++

I've coded a program to practice using header and class.
So the project have three files.
main.cpp BigInteger.h BigInteger.cpp
I called class "BigInteger" in main.cpp
when I read the string from main,it shows correctly.
But when I using +,-,* operator.
It shows me the answer but add a '0' in front of the answer.
the following is my code
//main.cpp
#include "BigInteger.h"
int main() {
BigInteger a("-1234567890");
BigInteger b("234567891");
BigInteger ans1, ans2, ans3, ans4;
BigInteger c(a), d;
ans1 = a + b;
ans2 = a - c;
ans3 = c - b;
ans4 = a*b;
cout<<"a="; a.print();
cout<<"b="; b.print();
cout<<"c="; c.print();
cout<<"d="; d.print();
cout<<"a+b="; ans1.print();
cout<<"a-c="; ans2.print();
cout<<"c-b="; ans3.print();
cout<<"a*b="; ans4.print();
}
//header
#include <iostream>
#include <vector>
#include <string>
#define MAX_SIZE 80
using namespace std;
static const int ROWS=4, COLS=4;
class BigInteger{
private:
vector <int> digits;
bool positive; //正負數,0的正負設為正
void adding(const vector <int> &x,const vector <int> &y, vector <int> &z);
void subing(const vector <int> &x ,const vector <int> &y, vector <int> &z);
bool max(const vector <int> & x,const vector <int> & y);
void Reverse( vector <int> & r);
public:
BigInteger(string s);
BigInteger();
BigInteger(const BigInteger & r);
BigInteger & operator =(const BigInteger & r);
BigInteger operator +(const BigInteger & r);
BigInteger operator -(const BigInteger & r);
BigInteger operator *(const BigInteger & r);
void print();
};
//BigInteger.cpp
#include "BigInteger.h"
#include "math.h"
BigInteger::BigInteger(string s)
{
for(int i=0;i<s.size();i++) {
if(s[i]!='-') {
digits.push_back(s[i]-'0');
}
}
if(s[0]=='-') positive=true;
else positive=false;
}
BigInteger::BigInteger()
{
digits.push_back(0);
positive=false;
}
BigInteger::BigInteger(const BigInteger & x){
for(int i=0;i<x.digits.size();i++)
digits.push_back(x.digits[i]);
positive=x.positive;
}
BigInteger & BigInteger::operator =(const BigInteger & x){
for(int i=0;i<x.digits.size();i++)
digits.push_back(x.digits[i]);
positive=x.positive;
return (*this);
}
BigInteger BigInteger::operator +(const BigInteger & x){
BigInteger answer;
answer.digits.clear();
bool pre; //if the front one is bigger return true.
if(positive==x.positive){
answer.positive=positive;
adding(digits,x.digits,answer.digits);
}
else{
pre=max(digits,x.digits);
if(pre) subing(digits,x.digits,answer.digits);
else subing(x.digits,digits,answer.digits);
answer.positive=false;
if(positive&&pre) answer.positive=true;
if((!positive)&&(!pre)) answer.positive=true;
}
return answer;
}
BigInteger BigInteger::operator -(const BigInteger & x){
BigInteger answer;
answer.digits.clear();
bool pre=max(digits,x.digits);
if(positive!=x.positive){
answer.positive=true;
if(pre) adding(digits,x.digits,answer.digits);
else adding(x.digits,digits,answer.digits);
}
else if(positive&&x.positive){
if(pre) {
subing(digits,x.digits,answer.digits);
answer.positive=true;}
else {
subing(x.digits,digits,answer.digits);
answer.positive=false;}
}
else {
if(pre){
answer.positive=false;
subing(digits,x.digits,answer.digits);}
else {
answer.positive=true;
subing(x.digits,digits,answer.digits);
}
}
return answer;
}
BigInteger BigInteger::operator *(const BigInteger & x){
BigInteger answer;
long long int a=0,b=0,ans=0;
int ten=1;
answer.digits.clear();
for(int i=digits.size()-1;i>=0;i--)
{
a+=digits[i]*ten;
ten*=10;
}
ten=1;
for(int i=x.digits.size()-1;i>=0;i--)
{
b+=x.digits[i]*ten;
ten*=10;
}
ans=a*b;
if(positive==x.positive) answer.positive=false;
else answer.positive=true;
while(ans>0)
{
answer.digits.push_back(ans%10);
ans=ans/10;
}
Reverse(answer.digits); //cause i use push_back ,it will be backwards
return answer;
}
void BigInteger::adding(const vector <int> & x,const vector <int> & y, vector <int> & z)
{
long long int a=0,b=0,ans=0;
BigInteger answer;
int ten=1;
answer.digits.clear();
for(int i=x.size()-1;i>=0;i--)
{
a+=x[i]*ten;
ten*=10;
}
ten=1;
for(int i=y.size()-1;i>=0;i--)
{
b+=y[i]*ten;
ten*=10;
}
ans=a+b;
while(ans>0)
{
z.push_back(ans%10);
ans=ans/10;
}
Reverse(z); //cause i use push_back ,it will be backwards
}
void BigInteger::subing(const vector <int> & x,const vector <int> & y, vector <int> & z){
long long int a=0,b=0,ans=0;
BigInteger answer;
int ten=1;
answer.digits.clear();
for(int i=x.size()-1;i>=0;i--)
{
a+=x[i]*ten;
ten*=10;
}
ten=1;
for(int i=y.size()-1;i>=0;i--)
{
b+=y[i]*ten;
ten*=10;
}
ans=a-b;
while(ans>0){
z.push_back(ans%10);
ans/=10;
}
Reverse(z); //cause i use push_back ,it will be backwards
}
bool BigInteger::max(const vector <int> & x,const vector <int> & y){
if(x.size()>y.size())
return true;
else return false;
}
void BigInteger::Reverse(vector <int> & z) {
int temp,j=z.size()-1;
for(int i=0;i<z.size()/2;i++)
{
temp=z[i];
z[i]=z[j];
z[j]=temp;
j-=1;
}
}
void BigInteger::print()
{
if(positive==true)
cout<<"-";
else
cout<<"";
//cout<<digits[0]<<endl;
for(int i=0;i<digits.size();i++){
cout<<digits[i];
}
cout<<endl;
// cout<<digits[6]<<digits[7]<<digits[8]<<digits[9]<<endl;
}

void BigInteger::print()
{
if(positive==true)
cout<<"-";
else
cout<<"";
//cout<<digits[0]<<endl;
for(int i=0;i<digits.size();i++){
cout<<digits[i];
}
cout<<endl;
// cout<<digits[6]<<digits[7]<<digits[8]<<digits[9]<<endl;
}
You can write like this
void BigInteger::print()
{
if(positive==true)
cout<<"-";
else
cout<<"";
//cout<<digits[0]<<endl;
bool not_zero_detect=false;
for(int i=0;i<digits.size();i++){
if(digits.size()!=1&& digits[i]==0 && not_zero_detect==false)
{
digits[i]=digits[i];
}
else
{
not_zero_detect=true;
cout<<digits[i];
}
}
cout<<endl;
// cout<<digits[6]<<digits[7]<<digits[8]<<digits[9]<<endl;
}
use bool like "not_zero_detect" to check whether it has zero in front of the number or not
PS: Thanks for sharing your homework :-)

Related

Problem with Segmentation Fault with doing operations on class

Sorry for variables not being all in engilsh. I have a problem when i try to do the += operation on class called Uklad3.
It is initialized the same way as previous ones, but with this one the segmentation failure comes up when i try to do any operations on it.
Any sugestions how to fix it? I am not a proffesional programmer.
I sumbited the whole code because I know it might be little hard to read, I am learning and this is for ma class.
The goal of the operation += is to add points from one coordinate system to the other. It is only the portion of the task but this is where I have a problem.
class punkt
{
private:
double x;
double y;
double z;
public:
punkt(){};
string name;
punkt(string,double,double,double);
double getx() const {return x;}
double gety() const {return y;}
double getz() const {return z;}
};
punkt::punkt(string name_,double x_, double y_, double z_)
{
name=name_;
x=x_;
y=y_;
z=z_;
}
class Uklad
{
public:
static const int size = 10;
punkt tablica[size];
string uklad_name;
void add(punkt);
int licznik;
Uklad(){licznik=0;};
Uklad(string);
Uklad & operator+=(const Uklad &var)
{
for(int i=0;i<var.licznik;i++)
{
tablica[licznik]=var.tablica[i];
licznik++;
}
}
Uklad & operator-= (const Uklad &var)
{
for(int i=0;i<licznik;i++)
{
for(int j=0;j<var.licznik;j++)
{
if((tablica[i].getx()==var.tablica[i].getx()) and (tablica[i].gety()==var.tablica[i].gety()) and (tablica[i].getz()==var.tablica[i].getz()))
{
for(int k=i;k<licznik;k++)
{
tablica[k]=tablica[k+1];
}
licznik--;
}
}
}
}
};
Uklad::Uklad(string uklad_name_)
{
uklad_name=uklad_name_;
cout<<"Tworze uklad"<<endl;
}
void Uklad::add(punkt toAdd)
{
if(licznik<size)
{
tablica[licznik]=toAdd;
licznik++;
}
}
}
ostream & operator<<(ostream &s, const punkt &Punkt)
{
cout<<Punkt.name<<" "<<Punkt.getx()<<" "<<Punkt.gety()<<" "<<Punkt.getz();
return s<<" ";
}
ostream & operator<<(ostream &s, const Uklad &uklad)
{
for(int i=0;i<uklad.licznik;i++)
{
if(i==uklad.licznik-1) cout<<uklad.tablica[i]<<" ";
else
cout<<uklad.tablica[i]<<"; ";
}
return s<<" ";
}
int main()
{
//1.
string name1,name2,name3;
cin>>name1;
cin>>name2;
Uklad uklad1(name1);
Uklad uklad2(name2);
//2.
const int M=2;
double xtemp, ytemp, ztemp;
string nametemp;
string xs,ys,zs;
for(int i=0;i<M;i++)
{
cin>>nametemp;
cin>>xtemp;
cin>>ytemp;
cin>>ztemp;
punkt punktT(nametemp,xtemp,ytemp,ztemp);
uklad1.add(punktT);
}
//3.
const int N=2;
double xtemp2, ytemp2, ztemp2;
string nametemp2;
string xs2,ys2,zs2;
for(int i=0;i<N;i++)
{
cin>>nametemp2;
cin>>xtemp2;
cin>>ytemp2;
cin>>ztemp2;
punkt punktT2(nametemp2,xtemp2,ytemp2,ztemp2);
uklad2.add(punktT2);
}
//4.
cin>>name3;
Uklad uklad3(name3);
//5.
uklad3+=uklad1;
cout<<uklad3;
return 0;
}
static const int size = 10;
You make array about 10 size and after all this loops you go out of range of the array. That's why you have this error. You can give it higher size. Or you can use vectors. In case of using array you must be sure you will not go out of range.
I formated the code and add initializer to licznik. This code haven't segmentation fault error
class punkt
{
private:
double x;
double y;
double z;
public:
punkt(){};
string name;
punkt(string,double,double,double);
double getx() const {return x;}
double gety() const {return y;}
double getz() const {return z;}
};
punkt::punkt(string name_,double x_, double y_, double z_)
{
name=name_;
x=x_;
y=y_;
z=z_;
}
class Uklad
{
public:
static const int size = 10;
punkt tablica[size];
string uklad_name = "";
void add(punkt);
int licznik = 0;
Uklad(){licznik=0;};
Uklad(string);
Uklad& operator+=(const Uklad &var)
{
for(int i=0;i<var.licznik;i++)
{
cout << licznik << " += ";
tablica[licznik]=var.tablica[i];
licznik++;
}
return *this;
}
Uklad & operator-= (const Uklad &var)
{
for(int i=0;i<licznik;i++)
{
for(int j=0;j<var.licznik;j++)
{
cout << i << " -=";
if((tablica[i].getx()==var.tablica[i].getx()) and (tablica[i].gety()==var.tablica[i].gety()) and (tablica[i].getz()==var.tablica[i].getz()))
{
for(int k=i;k<licznik;k++)
{
tablica[k]=tablica[k+1];
}
licznik--;
}
}
}
return *this;
}
};
Uklad::Uklad(string uklad_name_)
{
licznik = 0;
uklad_name=uklad_name_;
cout << "Tworze uklad" << endl;
}
void Uklad::add(punkt toAdd)
{
if(licznik<size)
{
tablica[licznik]=toAdd;
licznik++;
}
}
ostream & operator<<(ostream &s, const punkt &Punkt)
{
cout<<Punkt.name<<" "<<Punkt.getx()<<" "<<Punkt.gety()<<" "<<Punkt.getz();
return s<<" ";
}
ostream & operator<<(ostream &s, const Uklad &uklad)
{
for(int i=0;i<uklad.licznik;i++)
{
if(i==uklad.licznik-1) cout<<uklad.tablica[i]<<" ";
else
cout<<uklad.tablica[i]<<"; ";
}
return s<<" ";
}
int main()
{
//1.
string name1,name2,name3;
cin>>name1;
cin>>name2;
Uklad uklad1(name1);
Uklad uklad2(name2);
//2.
const int M=2;
double xtemp, ytemp, ztemp;
string nametemp;
string xs,ys,zs;
for(int i=0;i<M;i++)
{
cin>>nametemp;
cin>>xtemp;
cin>>ytemp;
cin>>ztemp;
punkt punktT(nametemp,xtemp,ytemp,ztemp);
uklad1.add(punktT);
}
//3.
const int N=2;
double xtemp2, ytemp2, ztemp2;
string nametemp2;
string xs2,ys2,zs2;
for(int i=0;i<N;i++)
{
cin>>nametemp2;
cin>>xtemp2;
cin>>ytemp2;
cin>>ztemp2;
punkt punktT2(nametemp2,xtemp2,ytemp2,ztemp2);
uklad2.add(punktT2);
}
//4.
cin>>name3;
Uklad uklad3(name3);
//5.
uklad3+=uklad1;
cout<<uklad3;
return 0;
}

Operator Overloading problem with screen insertion operator <<

I have overloaded all the operators properly but the relational operators are giving me error while using them with cout . i have tried alot, it gives this error:
[Error] no match for 'operator<<' (operand types are 'GrandInt' and '<unresolved overloaded function type>')
#include <iostream>
#include<string.h>
using namespace std;
class GrandInt{
string a;
public:
GrandInt(){
a="";
}
GrandInt(long long unsigned int n){
a=to_string(n);
}
GrandInt(string n){
a=n;
}
GrandInt(const GrandInt &x){
a=x.a;
}
GrandInt operator+(GrandInt &x){
char *ap= new char [a.length()+1];
int al=a.length();
strcpy(ap,a.c_str());
char *xp= new char [x.a.length()+1];
int xl=x.a.length();
strcpy(xp,x.a.c_str());
for(;*ap!='\0';ap++){}
for(;*xp!='\0';xp++){}
int rl;
if(xl>al)
rl=xl+1;
else
rl=al+1;
char *r=new char [rl+1];
ap--;xp--;
int ac,xc,sum,cary=0,c=0;
for(;al>=0||xl>=0;al--,xl--,ap--,xp--,r++,c++){
if(al>0)
ac=*ap-48;
else
ac=0;
if(xl>0)
xc=*xp-48;
else
xc=0;
sum=ac+xc+cary;
if(sum>9){
cary=sum/10;
sum=sum%10;
}
else
cary=0;
*r=sum+48;
}
r--;
if(*r=='0')
{ r--;c--;}
GrandInt temp;
for(;c>0;c--,r--){
temp.a=temp.a+*r;
}
return temp;
}
GrandInt operator-(GrandInt &x){
char *ap= new char [a.length()+1];
int al=a.length();
strcpy(ap,a.c_str());
char *xp= new char [x.a.length()+1];
int xl=x.a.length();
strcpy(xp,x.a.c_str());
for(;*ap!='\0';ap++){}
for(;*xp!='\0';xp++){}
int rl=al;
char *r=new char [rl+1];
ap--;xp--;
int ac,xc,sum,cary=0,c=0;
for(;al>=0||xl>=0;al--,xl--,ap--,xp--,r++,c++){
if(xl>0)
xc=*xp-48;
else
xc=0;
ac=*ap-48;
if(ac<xc){
cary=10;
ap--;
*ap=*ap-1;
ap++;
}
sum=ac-xc+cary;
*r=sum+48;
cary=0;
}
r--;
if(*r=='0')
{ r--;c--;}
GrandInt temp;
for(;c>0;c--,r--){
temp.a=temp.a+*r;
}
return temp;
}
bool operator>(GrandInt &x){
if(a.compare(x.a)>0)
return 0;
else
return 1;
}
friend ostream &operator <<(ostream &out,GrandInt x){
cout<<x.a;
return out;
}
friend istream &operator>>(istream &in, GrandInt x){
cin>>x.a;
return in;
}
};
int main()
{
//starting with small numbers
GrandInt num1("546");
GrandInt num2("60");
cout<<num1+num2<<endl;//606
cout<<num1-num2<<endl;//486
cout<<num1>num2<<endl;//1
}```
You are not using the ostream& out in the overloaded operators. Try this:
friend ostream &operator<<(ostream &out, GrandInt x) {
out << x.a;
return out;
}
friend istream &operator>>(istream &in, GrandInt x) {
in >> x.a;
return in;
}
And in the main function:
cout<< (num1>num2) << endl; // parenthesis needed because of operator precedence

where's the error and why this program is wrong?

I'm doing an exercise for homework where i have to create a class for a fraction , but when i was coding i got in trouble with the overloading of the operator << ,and i don't understand where's the error because when the program reads the input the two numbers(numerator,denominator) are saved correctly, but when i try to print in output the fraction it gives me a random number; why?
#include <iostream>
using namespace std;
class Frazione{
private:
int num;
int den;
public:
Frazione operator+(Frazione f2){
Frazione risultato;
risultato.den=MCM(f2.den);
risultato.num=(num*(risultato.den/den))+(f2.num*(risultato.den/f2.den));
return risultato;
}
int MCM(int a){
int min;
int k;
if(den>a){
min=a;
}
else{
min=den;
}
for(int i=min;!(den%i==0 && a%min==0);i+=min){
k=i;
}
return k;
}
void setn(int a){
num=a;
}
void setd(int a){
den=a;
}
int getn(){
return num;
}
int getd(){
return den;
}
};
istream& operator>>(istream& in,Frazione f){
int n,d;
cout<<"Dimmi il numeratore"<<endl;
in>>n;
cout<<"Dimmi il denominatore"<<endl;
in>>d;
f.setn(n);
f.setd(d);
return in;
}
ostream& operator<<(ostream& out,Frazione& f){
out<<f.getn();
out<<"/";
out<<f.getd();
return out;
}
int main(){
Frazione f1,f2,f3;
cin>>f1;
cout<<f1;
cin.get();
return 0;
}
Currently don't pay attention to funciont MCM and operator+ because they are function that i have to implement then i'll solve this plobem.
You have missed the reference of the second parameter here:
istream& operator>>(istream& in,Frazione &f)
The parameter f is only accessible by reference.

Memory leak,copy constructor,assign operator

Everthing is in the code
Here is code. Constructor's.
Polynomial::Polynomial()
{
base=0;
Coefficients=new int [base+1];
Coefficients[0]=0;
}
Basically creates Poly equals to 0;
Polynomial::Polynomial(const unsigned int length,const int* table)
{
base=length;
bool a=false;
for(int i=length;i>=0;i--)
{
if(table[i]==1&&a==false)
{
a=true;
Coefficients=new int[base+1];
};
if(table[i]==0&&a==false)
{
base--;
};
if(a==true)
Coefficients[i]=table[i];
}
}
Here we create Poly with given length(it can be higher than Poly base)
I think so far everything is ok.
Now copy constructor:
Polynomial::Polynomial(const Polynomial& P)
{
base = P.base;
Coefficients=new int[base+1];
for(unsigned int i=0; i<base+1;i++)
{
Coefficients[i]=P.Coefficients[i];
}
}
And assign operator:
Polynomial& Polynomial::operator =(const Polynomial &P)
{
base=P.base;
for(unsigned int i=0;i<P.base+1;i++)
Coefficients[i]= P.Coefficients[i];
return *this;
}
I think there is smth wrong with this because when i overloaded + operator
And created Polynomial a,u,v;
When i typed a=v+u;
Sometimes i had garbage values and " Process returned -1073741819 (0xC0000005)"
I've read some about switch/copy but is there simple solution in my code that I am missing on?
Polynomial operator +(const Polynomial& a,const Polynomial& b)
{
Polynomial c;
if(a.base>=b.base)
c.base=a.base;
else
c.base=b.base;
c.Coefficients=new int[c.base+1];
for(unsigned int i=0;i<c.base+1;i++)
{
c.Coefficients[i]=0;
};
for(unsigned int i=0;i<b.base+1;i++)
{
c.Coefficients[i]=b.Coefficients[i];
};
for(unsigned int i=0;i<a.base+1;i++)
{
c.Coefficients[i]+=a.Coefficients[i];
}
return c;
}
Here is destructor
Polynomial::~Polynomial()
{
delete []Coefficients;
}
+= operator
Polynomial& Polynomial::operator +=(const Polynomial& a)
{
if(a.base>base)
{
base=a.base;
Coefficients = (int*)realloc(Coefficients, (base+1)*sizeof(int));
for(unsigned int i=0;i<base+1;i++)
{
if(Coefficients[i]!=0&&Coefficients[i]!=1)
{
Coefficients[i]=0;
}
Coefficients[i]+=a.Coefficients[i];
}
}
if(a.base<=base)
{
for(unsigned int i=0;i<a.base+1;i++)
{
Coefficients[i]+=a.Coefficients[i];
}
}
return *this;
}

Implementation of Polygon class

I am writing a program that contains three classes: They are point, line and polygon. I have written the first two, but I am having trouble with the last one.
This class has to have two constructors, one of them builds an object with a point (tip of polygon) and another one builds it with a line. These functions have to be as follows:
polygon(point** arr,int size) and polygon(line** arr,int size).
I don't know why point and line are pointer to pointer? What are the attributes of the polygon class and how can I write polygon's constructor?
class point
{
private:
int first;
int second;
public:
point(void);
point (int x,int y);
point (const point& other);
int getX();
int getY();
int distance(point* other);//distance of two point
line* Line(point*);//build a line with two point
polygon* triangle(point*,point*);//build a triangle with three point
~point(void);
};
point::point(void)
{
first=0;
second=0;
}
point::point (int x,int y)
{
first=x;
second=y;
}
point::point(const point& other)
{
first=other.first;
second=other.second;
}
int point::gha(int a)
{
if(a>=0)
return a;
else
return -a;
}
int point::pow(int a)
{
return a*a;
}
int point::getX(){return first;}
int point::getY(){return second;}
int point::distance(point* other)
{
int d= sqrt((pow(first-other->first))+(pow(second-other->second)));
return d;
}
line* point::Line(point* other)
{
line l(this,other);
return &l;
}
polygon* point::triangle(point*,point*){
}
point::~point(void)
{
}
////////////////////////////
class line
{
private:
int m;
int c;
public:
line(void);
line(point*,point*);
line(int ,point*);
bool isParallel(line*);
bool isPrependicular(line*);
point* intersection(line*);
line* parallel(point*);
polygon* triangle(line*,line*);
~line(void);
};
line::line(void)
{
m=1;
c=0;
}
line::line(point* a,point* b)
{
m=((a->getY())-b->getY())/(a->getX()-b->getX());
c=a->getY()-(m*(a->getX()));
}
line::line(int dip,point* a)
{
m=dip;
c=a->getY()-(dip*(a->getX()));
}
bool line:: isParallel(line* other)
{
if(m==other->m)
return true;
else
return false;
}
bool line::isPrependicular(line* other)
{
if((m*other->m)==1 || (m*other->m)==-1)
return true;
else
return false;
}
point* line::intersection(line* other)
{
int x=(other->c-c)/(m-other->m);
int y=(m*x)+c;
point p (x,y);
return &p;
}
line* line::parallel(point* other)
{
line l(m,other);
return &l;
}
line::~line(void)
{
}
///////////////////////////////////
class polygon
{
private:
int count;
point* tip;
line* l;
public:
polygon(void);
polygon(point** arr,int size);
polygon(line** arr,int size);
bool isTriangle();
bool isSquare();
~polygon(void);
};