Am definit o clasa care permite calcului cu numere mari implementata cu templated string si pentru a permite o accesibilitate user-friendly, operatori aritmetici au fost de asemenea adaptati pentru a permite calculul. Din nefericire avand in vedere ca C++
este limitat de arhitectura procesorului pentru a executa calcule in anumite intervale, consider ca va fi de folos aceasta clasa.
Avem header-ul unde se afla definitile functilor constructorul si destructorul.
#pragma once #include<string> #include<algorithm> #include<vector> #include<utility> #include<iostream> using namespace std; class BigInt { private: string s; bool mai_mic_sau_egal(string s,string ss); bool mai_mic(string s,string ss); bool mai_mare(string s, string ss); bool mai_mare_sau_egal(string s,string ss); string sx(string s,string ss); string dx(string s,string ss); string px(string s,string ss); string pow(string s,string ss); pair<string,string> ddx(string s,string ss); void convert_to_int(); void convert_to_float(); public: BigInt(string n); ~BigInt()=default; bool operator<(BigInt ss); bool operator<=(BigInt ss); bool operator==(BigInt ss); bool operator>(BigInt ss); bool operator>=(BigInt ss); void operator=(string ss); void operator=(BigInt ss); string operator+(BigInt ss); string operator-(BigInt ss); string operator*(BigInt ss); string operator^(BigInt ss); operator int(); operator float(); //if you are sure the number is within c++ bounds you can convert it to the wanted value int to_int(); double to_double(); long long to_ll(); unsigned long long to_ull(); friend ostream& operator<<(ostream& os, BigInt &s); friend istream& operator>>(istream& is, BigInt &s); pair<string,string> operator/(BigInt ss); //returns a pair containing on first the quotient and on second the reminder of the division string sqrt(); };
Iar aici implementarea functilor impreuna cu functile de tip get/set.
#include "BigInt.h" BigInt::BigInt(string n){ s=n; } string BigInt::operator+(BigInt ss) { return sx(s,ss.s); } string BigInt::operator*(BigInt ss) { return px(s,ss.s); } void BigInt::operator=(string ss) { s=ss; } string BigInt::operator-(BigInt ss) { return dx(s,ss.s); } bool BigInt::operator<(BigInt ss) { return mai_mic(s,ss.s); } string BigInt::sqrt() { string rezerve=s; string rez,temp,aux,p; int ok=0,k,o=0,c=0,l; if(s[0]=='-') ok=1,s.erase(s.begin()+0); if(s.find('.')==-1) { l=s.size(); if(s.size()%2) k=s.size()/2+1; else k=s.size()/2; } else { k=s.find('.'),s.erase(s.begin()+k); l=k; if(k%2) k=k/2+1; else k/=2; } s+="0000000000000000"; if(l%2) { o=1; temp+=s[0]; while(c<9) { aux+=to_string(c++); p=px(aux,aux); if(!mai_mic_sau_egal(p,temp)) break; aux.pop_back(); } rez+=--aux[0]; p=dx(temp,px(aux,aux)); while(p[0]=='0') p.erase(p.begin()+0); if(p!="") temp=p; else temp=""; } for(int i=o;i<s.size();) { c=-1; temp+=s[i++]; temp+=s[i++]; if(temp=="00") { rez+='0'; temp=""; continue; } if(aux!="") aux=px(rez,"2"); else { while(c<9) { c++; if(c==10) { aux+=to_string(--c); p=px(aux,aux); break; } else aux+=to_string(c); p=px(aux,aux); if(!mai_mic_sau_egal(p,temp)) { if(c==9) c--; break; } if(c!=9) aux.pop_back(); } if(c==9) rez+=to_string(c); else rez+=--aux[0]; p=dx(temp,px(aux,aux)); while(p[0]=='0') p.erase(p.begin()+0); if(p!="") temp=p; else temp=""; continue; } while(c<9) { c++; if(c==10) { aux+=to_string(--c); p=px(aux,to_string(c)); break; } else aux+=to_string(c); p=px(aux,to_string(c)); if(!mai_mic_sau_egal(p,temp)) { if(c==9) c--; break; } if(c!=9) aux.pop_back(); } if(c==9) rez+=to_string(c); else rez+=--aux[aux.size()-1]; c=aux[aux.size()-1]-'0'; p=dx(temp,px(aux,to_string(c))); while(p[0]=='0') p.erase(p.begin()+0); if(p!="") temp=p; else temp=""; if(rez.size()-k>8 && k<rez.size()) break; } rez.insert(rez.begin()+k,'.'); c=rez.find('.'); while(rez.size()-1-c>8) rez.pop_back(); if(ok) rez+='i'; s=rezerve; return rez; } string BigInt::sx(string s,string ss) { int ls=0,lss=0,o1=0,o2=0,lmax,len; if(s.find('.')!=-1) ls=s.find('.'),o1=1; if(ss.find('.')!=-1) lss=ss.find('.'),o2=1; lmax=max(ls,lss); len=max(s.size(),ss.size()); if(o1) { s.erase(s.begin()+ls),ls--; ls=s.size()-1-ls; } if(o2) { ss.erase(ss.begin()+lss),lss--; lss=ss.size()-1-lss; } len=max(s.size(),ss.size()); if(ls>lss) for(int i=1;i<=ls-lss;i++) ss+='0'; else if(lss>ls) for(int i=1;i<=lss-ls;i++) s+='0'; int t=0; if (s.length()>ss.length()) swap(s,ss); string str=""; int n1=s.length(),n2=ss.length(); int dif=n2-n1; for(int i=n1-1;i>=0;i--) { int sum=((s[i]-'0')+(ss[i+dif]-'0')+t); str.push_back(sum%10+'0'); t=sum/10; } for(int i=n2-n1-1;i>=0;i--) { int sum=((ss[i]-'0')+t); str.push_back(sum%10+'0'); t=sum/10; } if(t) str.push_back(t+'0'); reverse(str.begin(),str.end()); if(ls || lss) str.insert(str.begin()+lmax+(str.size()-len),'.'); return str; } string BigInt::dx(string s,string ss) { int ls=0,lss=0,o1=0,o2=0,lmax,len; if(s.find('.')!=-1) ls=s.find('.'),o1=1; if(ss.find('.')!=-1) lss=ss.find('.'),o2=1; lmax=max(ls,lss); len=max(s.size(),ss.size()); if(o1) { s.erase(s.begin()+ls),ls--; ls=s.size()-1-ls; } if(o2) { ss.erase(ss.begin()+lss),lss--; lss=ss.size()-1-lss; } len=max(s.size(),ss.size()); if(ls>lss) for(int i=1;i<=ls-lss;i++) ss+='0'; else if(lss>ls) for(int i=1;i<=lss-ls;i++) s+='0'; int ok=0; if(mai_mic_sau_egal(s,ss) && s!=ss) swap(s,ss),ok=1; string str = ""; if(s[0]=='0') return "0"; int n1=s.length(),n2=ss.length(); int dif=n1-n2; int t=0; for(int i=n2-1;i>=0;i--) { int sub=((s[i+dif]-'0')-(ss[i]-'0')-t); if(sub<0) sub+=10,t=1; else t=0; str.push_back(sub+'0'); } for(int i=n1-n2-1;i>=0;i--) { if(s[i]=='0'&&t) { str.push_back('9'); continue; } int sub=((s[i]-'0')-t); if (i>0||sub>0) str.push_back(sub+'0'); t=0; } reverse(str.begin(),str.end()); if(ls || lss) str.insert(str.begin()+lmax+(str.size()-len),'.'); while(str[0]=='0' && str.size()>1) str.erase(str.begin()+0); if(ok) str.insert(str.begin()+0,'-'); return str; } string BigInt::px(string s,string ss) { int ls=0,lss=0,o1=0,o2=0,ls1=0,ls2=0,lmax; if(s.find('.')!=-1) ls=s.find('.'),o1=1,ls1=ls; if(ss.find('.')!=-1) lss=ss.find('.'),o2=1,ls2=lss; if(o1) ls1=s.size()-1-ls1; if(o2) ls2=ss.size()-1-ls2; lmax=ls1+ls2; if(o1) { s.erase(s.begin()+ls),ls--; ls=s.size()-1-ls; } if(o2) { ss.erase(ss.begin()+lss),lss--; lss=ss.size()-1-lss; } if(ls>lss) for(int i=1;i<=ls-lss;i++) ss+='0'; else if(lss>ls) for(int i=1;i<=lss-ls;i++) s+='0'; int n1=s.size(); int n2=ss.size(); if(n1==0||n2==0) return "0"; vector<int> rez(n1+n2,0); int i_n1=0; int i_n2=0; for(int i=n1-1;i>=0;i--) { int t=0; int n1=s[i]-'0'; i_n2=0; for(int j=n2-1;j>=0;j--) { int n2=ss[j]-'0'; int sum=n1*n2+rez[i_n1+i_n2]+t; t=sum/10; rez[i_n1+i_n2]=sum%10; i_n2++; } if(t>0) rez[i_n1+i_n2]+=t; i_n1++; } int i=rez.size()-1; while(i>=0 && rez[i]==0) i--; if(i==-1) return "0"; string sss=""; while(i>=0) sss+=to_string(rez[i--]); if(ls1 || ls2) sss.insert(sss.begin()+(sss.size()-1-lmax),'.'); return sss; } bool BigInt::mai_mic_sau_egal(string s,string ss) { int n1=s.length(),n2=ss.length(); if(n1<n2) return true; if(n1>n2) return false; for(int i=0;i<n1;i++) { if(s[i]<ss[i]) return true; else if(s[i]>ss[i]) return false; } return true; } void BigInt::operator=(BigInt ss) { s=ss.s; } pair<string,string> BigInt::ddx(string s, string ss) { string rest="0"; int m=2,ls=0,lss=0,o1=0,o2=0,p1=0,p2=0; if(s[0]=='-' || ss[0]=='-') { m=1; if(s[0]=='-' && ss[0]!='-') p1=1; if(s[0]!='-' && ss[0]=='-') p2=1; } if(s[0]=='-' && ss[0]=='-') m=0; if(s[0]=='-') s.erase(s.begin()+0); if(ss[0]=='-') ss.erase(ss.begin()+0); if(s.find('.')!=-1) ls=s.find('.'),o1=1; if(ss.find('.')!=-1) lss=ss.find('.'),o2=1; if(o1) { s.erase(s.begin()+ls),ls--; ls=s.size()-1-ls; } if(o2) { ss.erase(ss.begin()+lss),lss--; lss=ss.size()-1-lss; } if(ls>lss) for(int i=1;i<=ls-lss;i++) ss+='0'; else if(lss>ls) for(int i=1;i<=lss-ls;i++) s+='0'; if(ss=="1") { return make_pair(s+".000000","0"); } if(s=="0") { return make_pair("0.000000","0"); } string rez; if(mai_mic(s,ss)) rez="0."; if(mai_mic(s,ss)) rest=s; while(mai_mic(s,ss)) { s+='0'; if(!mai_mic(s,ss) || (rez.size()-1-rez.find('.')==6 && rez.find('.')!=-1)) break; rez+='0'; } if(rez.find('.')!=-1) { if(rez.size()-1-rez.find('.')==6) return make_pair(rez,rest); else if(rez.size()-1-rez.find('.')<6 && rez.find('.')!=-1) { string temp; while(rez.size()-1-rez.find('.')<6) { int ap=0; while(!mai_mic(s,ss)) s=dx(s,ss),ap++; rez+=to_string(ap); s+='0'; } return make_pair(rez,rest); } } string temp; int j,k=s.size(),ap=0; s+="000000"; for(int i=0;i<s.size() && mai_mic(temp,ss);i++) temp+=s[i],j=i+1; while(!mai_mic(temp,ss)) temp=dx(temp,ss),ap++; rez+=to_string(ap); for(;j<s.size();j++) { if(rez.find('.')!=-1 && rez.size()-1-rez.find('.')==6) { if(m==1) rez.insert(rez.begin()+0,'-'); if(((p1 && !p2) || !m) && rest!="0") rest.insert(rest.begin()+0,'-'); return make_pair(rez,rest); } ap=0; if(j==k) { rez+='.'; rest=temp; ls=max(ls,lss); if(ls) { rest.insert(rest.begin()+rest.size()-ls,'.'); if(rest[0]=='.') rest.insert(rest.begin(),'0'); } } if(temp[0]=='0') temp="",temp+=s[j]; else temp+=s[j]; if(temp[0]=='0') { rez+='0'; continue; } while(mai_mic(temp,ss) && j<s.size()) { rez+='0',temp+=s[++j]; if(rez.size()-1-rez.find('.')==6 && rez.find('.')!=-1) { if(m==1) rez.insert(rez.begin()+0,'-'); if(((p1 && !p2) || !m) && rest!="0") rest.insert(rest.begin()+0,'-'); return make_pair(rez,rest); } } while(!mai_mic(temp,ss)) temp=dx(temp,ss),ap++; rez+=to_string(ap); } if(m==1) rez.insert(rez.begin()+0,'-'); if(((p1 && !p2) || !m) && rest!="0") rest.insert(rest.begin()+0,'-'); return make_pair(rez,rest); } pair<string, string> BigInt::operator/(BigInt ss) { return ddx(s,ss.s); } bool BigInt::mai_mic(string s, string ss) { int n1=s.length(),n2=ss.length(); if(n1<n2) return true; if(n1>n2) return false; for(int i=0;i<n1;i++) { if(s[i]<ss[i]) return true; else if(s[i]>ss[i]) return false; } return false; } bool BigInt::operator<=(BigInt ss) { return mai_mic_sau_egal(s,ss.s); } bool BigInt::operator==(BigInt ss) { return s==ss.s; } bool BigInt::mai_mare(string s, string ss) { int n1=s.length(),n2=ss.length(); if(n1<n2) return false; if(n1>n2) return true; for(int i=0;i<n1;i++) { if(s[i]<ss[i]) return false; else if(s[i]>ss[i]) return true; } return false; } bool BigInt::mai_mare_sau_egal(string s, string ss) { int n1=s.length(),n2=ss.length(); if(n1<n2) return false; if(n1>n2) return true; for(int i=0;i<n1;i++) { if(s[i]<ss[i]) return false; else if(s[i]>ss[i]) return true; } return true; } bool BigInt::operator>(BigInt ss) { return mai_mare(s,ss.s); } bool BigInt::operator>=(BigInt ss) { return mai_mare_sau_egal(s,ss.s); } string BigInt::pow(string s, string ss) { if(ss=="0") return "1"; string rez="1"; for(string i="1"; mai_mic_sau_egal(i,ss);i=sx(i,"1")) rez=px(rez,s); return rez; } string BigInt::operator^(BigInt ss) { return pow(s,ss.s); } void BigInt::convert_to_int() { int point=s.find('.'); if(point!=-1) s.resize(point); } void BigInt::convert_to_float() { int point=s.find('.'); if(point==-1) s+='.'; for(int i=1;i<=15;i++) s+='0'; } BigInt::operator int() { convert_to_int(); return 0; } BigInt::operator float() { convert_to_float(); return 0; } ostream &operator<<(ostream &stream, BigInt& ss) { cout<<ss.s; return stream; } istream &operator>>(istream &is, BigInt& ss) { is>>ss.s; return is; } int BigInt::to_int() { return stoi(s); } double BigInt::to_double() { return stod(s); } long long BigInt::to_ll() { return stoll(s); } unsigned long long BigInt::to_ull() { return stoull(s); }
Si programul driver cu exemple demo de test.
#include<bits/stdc++.h> #include "BigInt.h" using namespace std; int main() { BigInt s("400.5"); // or s=400 is the same either by assignation or by constructor BigInt ss("50"); cout<<s+ss<<endl; cout<<s-ss<<endl; cout<<s*ss<<endl; pair<string,string> p=s/ss; cout<<p.first<<" "<<p.second<<endl; cout<<s.sqrt()<<endl; s="3.5"; s.operator int(); cout<<s<<endl; s.operator float(); cout<<s<<endl; s="3"; ss="3"; cout<<(s^ss)<<endl; ss=s; cin>>s; cout<<s; cout<<s.to_double(); }
End
Probleme ataşate
Nr. | Problema | Clasa | Dificultate | Operații I/O |
---|---|---|---|---|
1 | #2332 - primXXL | 9 | medie | fișiere |
2 | #2393 - SumaXXL | 9 | medie | fișiere |
3 | #2890 - Base Converter | 10 | dificilă | fișiere |
4 | #3054 - PrimeXXL | 10 | dificilă | fișiere |
5 | #3053 - EvenOddXXL | 10 | ușoară | fișiere |
6 | #2928 - SqrtXXL | 10 | dificilă | consola |
7 | #2689 - PalXXL | 9 | medie | consola |
8 | #2410 - ProdusXXL | 9 | medie | fișiere |