#include <iostream>
#include "bignum.h"
using namespace std;
int main() {
try {
// bignum a;
// //a.realloc();
// std::cout<<'\n'<<std::string(50,'_')<<endl;
bignum b("-345");
std::cout<<'\n'<<std::string(50,'_')<<endl;
bignum c("4567");
std::cout<<'\n'<<std::string(50,'_')<<endl;
// bignum d("7891");
// std::cout<<'\n'<<std::string(50,'_')<<endl;
// bignum e("1111");
// std::cout<<'\n'<<std::string(50,'_')<<endl;
// bignum f("1111");
// std::cout<<'\n'<<std::string(50,'_')<<endl;
// // bignum d("4-567");
// std::cout<<'\n'<<std::string(50,'_')<<endl;
// cout<<"b+c="<<b+c<<endl; ///4�912
// std::cout<<'\n'<<std::string(50,'_')<<endl;
// o(d+c) ///12�458
// std::cout<<'\n'<<std::string(50,'_')<<endl;
// o(e+f)
// std::cout<<'\n'<<std::string(50,'_')<<endl;
// o(e+c)
// std::cout<<'\n'<<std::string(50,'_')<<endl;
// // test("1111117","1111117");
// bignum 'z("");
// std::cout<<'\n'<<std::string(50,'*')<<endl;
// o(bignum("-5")-bignum("4"))
// o(bignum("5")-bignum("4"))
// o(bignum("-5")-bignum("-4"))
// o(bignum("5")-bignum("-4"))
// std::cout<<'\n'<<std::string(50,'*')<<endl;
// o(bignum("-4")-bignum("4"))
// o(bignum("4")-bignum("4")) //zle
// o(bignum("-4")-bignum("-4"))
// o(bignum("4")-bignum("-4"))
// std::cout<<'\n'<<std::string(50,'*')<<endl;
// o(bignum("-4")-bignum("5"))
// o(bignum("4")-bignum("5")) //zle
// o(bignum("-4")-bignum("-5"))
// o(bignum("4")-bignum("-5"))
// std::cout<<'\n'<<std::string(50,'_')<<endl;
o(b-c) // b�ad przekroczenie tablicy
} catch(bignum &) {
exit(-1);
} catch(bignum::formaterr &) {
exit(-2);
} catch(std::exception & e) {
std::cout<<e.what()<<std::endl;
exit(-3);
} catch(ERROR & e) {
std::cout<<e.what()<<std::endl;
exit(-4);
} catch(...) {
exit(-6);
}
return 0;
}
#include "bignum.h"
std::string filename() {
size_t pozslash=std::string(__FILE__).rfind('/');
if((pozslash+1))
return std::string(__FILE__).substr(pozslash+1);
size_t pozbackslash=std::string(__FILE__).rfind('\\');
if((pozbackslash+1))
return std::string(__FILE__).substr(pozbackslash+1);
return std::string(__FILE__);
}
size_t errornr{};
std::string clnam(const std::string& s="") {return s.size()? " in class "+s+' ':""; }
#define err(class) std::cout<<'\n'<<std::string(50,'v')<<'\n'<<"ERROR "<<filename()<<"<- error nr "<<errornr++ <<clnam(#class)<<'\n'<<std::string(50,'^')<<std::endl;//
#define o(x) std::cout<<'\n'<<#x<<'='<<x<<std::endl;
using std::cout;
using std::endl;
bignum::bignum(const std::string& longnum):size{longnum.size()} {
// o(size);
errornr=0;
switch(longnum.find('-')) {
case 0:
// o("ujemna liczba");
sign='-';
size--;
break;
case static_cast<size_t>(-1):
// o("dodatnie");
break;
default:
correct = false;
err(bignum);
std::cerr<<"bledna liczba 1"<<std::endl;
// exit(-1);
throw formaterr();
break;
}
// std::cout<<longnum.size()<<").";
if(longnum.size())
ptrlgnr=new char[longnum.size()];
else
throw errWymiar();
if(ptrlgnr)
for(auto it=longnum.cbegin(), end=longnum.cend(),last=end-1; it!=end; it++) {
switch(*it) {
case '0' ... '9':
ptrlgnr[last-it]=*it-'0';
break;
case '-':
ptrlgnr[last-it]=*it;
break;
case 0:
ptrlgnr[last-it]=*it;
break;
default:
correct=false;
err(bignum);
std::cout<<*it+'0'<<'|';
std::cerr<<"bledna liczba 2"<<std::endl;
throw formaterr::ferr;
break;
}
}
// for(size_t i=0; i+1<longnum.size(); i++)
// std::cout<<static_cast<short>(ptrlgnr[i])<<'\t';
// char lastdigit=ptrlgnr[longnum.size()-1];
// if(lastdigit=='-')
// std::cout<<static_cast<char>(lastdigit)<<'\t';
// else
// std::cout<<static_cast<short>(lastdigit)<<'\t';
// std::cout<<std::endl;
// std::cout<<'\n'<<std::string(50,'?')<<"\nkoniec konstruktora size="<<size<<'\n'<<std::string(50,'?')<<std::endl;
}
bignum::~bignum() {
if(ptrlgnr)
delete[]ptrlgnr;
// o("usuniento")
}
//bignum::bignum(const bignum& other) {
//
//}
bignum& bignum::operator=(const bignum& rhs) {
if(this == &rhs)
return *this; // handle self assignment
//assignment operator
return *this;
}
bignum operator + (const bignum& lhs,const bignum& rhs) {
char flag =(lhs.size>rhs.size)?1:0;
size_t size=(lhs.size>rhs.size)?lhs.size:rhs.size;
bignum* ptr{};
ptr=new bignum{std::string(size+1,char{})};
if(ptr==nullptr)
throw std::bad_alloc();
switch(flag) {
case 1: {
ptr->add(lhs,rhs/*, ptr*/);
break;
}
case 0: {
ptr->bignum::add(rhs,lhs/*, ptr*/);
break;
}
default:
err(bignum);
}
return *ptr;
}
bignum operator - (const bignum& lhs,const bignum& rhs) {
size_t size=(lhs.size>rhs.size)?lhs.size:rhs.size;
bignum temp(std::string(std::max(lhs.size,rhs.size),'0'));
int flag = 0b00;
if(rhs.sign=='+')
flag|=2;
if(lhs.sign=='+')
flag|=1;
// o(bitset<4>(flag))
if(temp.graterAbs(lhs,rhs)) //np |-5|>|4|=true
switch(flag) {
case 0:
// -5-(-4)= -(5-4)=-1
temp.subtract(lhs,rhs);
temp.sign='-';
break;
case 1:// oprzeciwnych znakach
//5-(-4)= 5+4=9
temp.add(lhs,rhs);
break;
case 2:// oprzeciwnych znakach
//-5-4= -(5+4)=-9
temp.add(lhs,rhs);
temp.sign='-';
break;
case 3:// obie dodatnie
//5-4= 5-4=1;
temp.subtract(lhs,rhs);
break;
default:
throw;
} else //np |-4|>|5|=false
switch(flag) {
case 0:
// -4-(-5)= -(4-5)=(5-4)=1
temp.subtract(rhs,lhs); //zmieniona kolejność funkcji
// temp.sign='-';
break;
case 1:// oprzeciwnych znakach
//4-(-5)= 4+5=9
temp.add(rhs,lhs);//zmieniona kolejność funkcji
break;
case 2:// oprzeciwnych znakach
//-4-5= -(5+4)=-9
temp.add(rhs,lhs);//zmieniona kolejność funkcji
temp.sign='-';
break;
case 3:// obie dodatnie
//4-5= -(5-4)=-1;
temp.subtract(rhs,lhs);//zmieniona kolejność funkcji
temp.sign='-';
break;
default:
throw;
}
temp.realloc(temp.ptrlgnr,10);
return temp;
}
std::ostream & operator << (std::ostream & os, const bignum & bn) {
size_t tabsize=bn.size;
//char * tab = bn.ptrlgnr;
os<< "(rozmiar Tablicy "<<tabsize<<") ";
bn.sign=='-'?os<<'-':os;
for(size_t i=tabsize-1; i<tabsize; i--)
os<<(short)bn.ptrlgnr[i];
os<<std::flush;
return os;
}
void bignum::add(const bignum & ptrbigger,const bignum &ptrlower/*, bignum* ptr*/) {
size_t bigger = ptrbigger.size;
size_t lower = ptrlower.size;
char mem{};
size_t i=0;
/// for(; i+lower<bigger; i++) { // pamientaæ by sumowaæ przy size_t -> i<bigger-lower <-tak pentla nieskoñczona
for(; i<lower; i++) {
// o((int)ptrbigger.ptrlgnr[i])o((int)ptrlower.ptrlgnr[i])o(ptrbigger.ptrlgnr[i]+ptrlower.ptrlgnr[i])o(ptrbigger.ptrlgnr[i]+ptrlower.ptrlgnr[i]+mem)
mem=ptrbigger.ptrlgnr[i]+ptrlower.ptrlgnr[i]+mem;
ptrlgnr[i]=mem%10;
// o((int)mem)
mem/=10;
// o((int)mem)
}
while(mem)
if(i<bigger) {
mem=ptrbigger.ptrlgnr[i]+mem;
//ptr->
ptrlgnr[i]=mem%10;
mem/=10;
i++;
} else {
//ptr->
ptrlgnr[i]=1; //mem%10=1;
break;
}
for(; i<bigger; i++) {
o(i) o(ptrbigger.size) o(size)
ptrlgnr[i]=ptrbigger.ptrlgnr[i];
}
while(!ptrlgnr[size-1])
size--; //je¿eli pierwsze 0
}
void bignum::subtract(const bignum & ptrbigger,const bignum &ptrlower, bignum* ptr) {
size_t bigger = ptrbigger.size;
size_t lower = ptrlower.size;
char mem{};
size_t i=0;
/// for(; i+lower<bigger; i++) { // pamientaæ by sumowaæ przy size_t -> i<bigger-lower <-tak pentla nieskoñczona
for(; i<lower; i++) {
if(ptrbigger.ptrlgnr[i]>ptrlower.ptrlgnr[i]) {
ptrlgnr[i]=ptrbigger.ptrlgnr[i]-ptrlower.ptrlgnr[i]+mem;
mem=0;
} else if(ptrbigger.ptrlgnr[i]<ptrlower.ptrlgnr[i]) {
ptrlgnr[i]=ptrbigger.ptrlgnr[i]+10-ptrlower.ptrlgnr[i]+mem;
mem=-1;
} else if(mem) {
ptrlgnr[i]=10+mem;
} else
ptrlgnr[i] = 0;
}
while(mem) // mem = -1;
if(i<bigger) // by nie wyjść za tablcę
if(ptrbigger.ptrlgnr[i]) {//ptrbigger.ptrlgnr[i] =(1,9);
ptrlgnr[i]=ptrbigger.ptrlgnr[i]+mem;
mem=0; //break;
i++;
} else {
ptrlgnr[i]=9; //0-1 => 10 - 1 =9, m=-1
} else
break;
for(; i<bigger; i++) {
ptr->ptrlgnr[i]=ptrbigger.ptrlgnr[i];//przepisujemy pozostałe liczby
}
while(!ptrlgnr[size-1])
if(size>1)
size--; //je¿eli pierwsze 0
else
break;
return;
}
void bignum::realloc(char * old,const size_t & newsize) {
if(!old)
throw std::bad_alloc();
char* newone=nullptr;
newone=new char[newsize+1] {};
if(newone)
for(size_t i=0; i<newsize; i++)
newone[i]=old[i];
else
throw std::bad_alloc(); // jeżeli nie udała się rezerwacja pamięci.
delete [] old;
old=newone;
newone=nullptr;
return;
}
bool bignum::graterAbs(const bignum &rhs) {
if(size>rhs.size)
return 1;
if(size<rhs.size)
return 0;
for(size_t i=size-1; i<size; i--)
if(ptrlgnr[i]!=rhs.ptrlgnr[i])
return ptrlgnr[i]>rhs.ptrlgnr[i]?1:0;
return 0;
}
bool bignum::graterAbs(const bignum &lhs,const bignum &rhs) {
if(lhs.size>rhs.size)
return 1;
if(lhs.size<rhs.size)
return 0;
for(size_t i=lhs.size-1; i<lhs.size; i--)
if(lhs.ptrlgnr[i]!=rhs.ptrlgnr[i])
return lhs.ptrlgnr[i]>rhs.ptrlgnr[i]?1:0;
return 0;
}
#ifndef BIGNUM_H
#define BIGNUM_H
#define o(x) std::cout<<'\n'<<#x<<'='<<x<<std::endl;
#define n(x) std::cout<<'\n'<<#x<<std::endl;
#include <iostream>
#include "Error.h"
class bignum {
public:
bignum(const std::string& longnum = "0");
bignum& operator=(const bignum& other);
virtual ~bignum();
// size_t Getm_Counter() { return m_Counter; }
// void Setm_Counter(unsigned int val) { m_Counter = val; }
void setnumtab(char* tabnum,size_t tabnumsize) {
ptrlgnr=tabnum;
size=tabnumsize;
}
struct formaterr {static formaterr ferr;};
//private:
public:
///**friend by nie robi� funkcji du�ej ilo�ci get() i set() **********************************//////
friend bignum operator + (const bignum& lhs,const bignum& rhs);
friend bignum operator - (const bignum& lhs,const bignum& rhs);
friend std::ostream & operator << (std::ostream & os, const bignum & bn);
///**funkcjie prywatne bo u�ycie publiczne moze da� dziwnne rezultaty ************************//////
void subtract(const bignum & ptrbigger,const bignum &ptrlower, bignum* ptr=nullptr);
void add(const bignum & ptrbigger,const bignum &ptrlower/*, bignum* ptr=nullptr*/);
void realloc(char * old=nullptr,const size_t & newsize=0);
bool graterAbs(const bignum &rhs);
bool graterAbs(const bignum &lhs,const bignum &rhs);
///**prywatnne zmienne************************************************************************//////
size_t size;
char * ptrlgnr{nullptr};
char sign{'+'};
bool correct =true;
//void add(const bignum & ptrbigger,const bignum &ptrlower, bignum* ptr);
};
#endif // BIGNUM_H
#ifndef ERROR_H
#define ERROR_H
struct ERROR {
virtual const char*const what()const throw() {return "Error";}
// virtual ~Error(){};
};
struct errWymiar:ERROR {
virtual const char*const what()const throw() {return "Dlugosc nie moze byc zerowa";}
};
struct unknownSign:ERROR {
virtual const char*const what()const throw() {return "nieznany znak";}
};
#endif // ERROR_H