高精整数数、纯小数类,支持加减法
之前加减法的强化版,里面自带了高精整数类,高精小数类,都分别定义了加减法
重点是技巧性可能不高,存档用吧
main.cpp:
#include<iostream> #include"num.h" #include<conio.h> int main() { num k1,k2; std::cout<<"欢迎使用高精度加减法器!!!"<<std::endl; int what; for(;;) { std::cout<<"输入1键执行加法,输入2键执行减法,0键退出。"<<std::endl; what=_getch(); if(!((what=='1')||(what=='2')||(what=='0'))) continue; if(what=='0') break; std::cout<<"请输入第一个数"<<std::endl; std::cin>>k1; std::cout<<"请输入第二个数"<<std::endl; std::cin>>k2; std::cout<<"结果是:"<<std::endl; if(what=='1') std::cout<<k1+k2<<std::endl; if(what=='2') std::cout<<k1-k2<<std::endl; } return 0; }
num.h:
#pragma once #ifndef NUM_H #define NUM_H #include<iostream> #include"exnum.h" #include"exrenum.h" class num { friend num operator+(const num&,const num&); friend num operator-(const num&,const num&); friend std::ostream& operator<<(std::ostream&,const num&); friend std::istream& operator>>(std::istream& is,num& in); private: exrenum ex; exnum n; public: void postion(); }; inline std::ostream& operator<<(std::ostream& os,const num& in) { os<<in.n<<'.'<<in.ex; return os; } #endif
exrenum.h:
#pragma once
#ifndef EXRENUM_H
#define EXRENUM_H
#include "exnum.h"
#include <iostream>
class exrenum
{
friend class num;
friend std::ostream& operator<<(std::ostream&,const exrenum&);
friend std::istream& operator>>(std::istream& is,exrenum& ienx);
friend exrenum operator+(const exrenum& iex1t,const exrenum& iex2t);
friend exrenum operator-(const exrenum& iex1,const exrenum& iex2);
friend void in_row(exrenum&,exrenum&);
friend void astyle(exrenum& iex);
public:
exrenum operator-()const;
exrenum():renum(),h_level(0){};
private:
long h_level;
exnum renum;
void make_in_low();
};
#endif
exnum.h:
#pragma once
#ifndef EXNUM_H
#define EXNUM_H
#include<list>
#include<iostream>
#include<sstream>
class exnum
{
friend class num;
typedef long num_type;
typedef std::list<num_type> num_list;
friend class exrenum;
friend exnum operator-(const exnum&,const exnum&);
friend exnum operator+(const exnum& e1,const exnum& e2);
friend bool operator<(const exnum& e1,const exnum& e2);
friend std::ostream& operator<<(std::ostream&,const exnum&);
friend std::istream& operator>>(std::istream&,exnum&);
friend exnum real_plus(const exnum& e1,const exnum& e2);
friend exnum real_mui(const exnum& e1,const exnum& e2);
friend std::istream& operator>>(std::istream& is,exrenum& ienx);
friend std::ostream& operator<<(std::ostream&,const exrenum&);
friend std::string re_format(long il,bool head,bool tail);
friend exrenum operator+(const exrenum& iex1t,const exrenum& iex2t);
friend exrenum operator-(const exrenum& iex1,const exrenum& iex2);
friend void in_row(exrenum& iex1,exrenum& iex2);
friend void astyle(exrenum& iex);
friend bool smaller(const exnum& e1,const exnum& e2);
public:
void push_back(long il)
{
num.push_back(il);
}
exnum():negative(false)
{
num.push_back(0);
}
exnum(const exnum& ien):num(ien.num),negative(ien.negative){}
exnum(const long il)
{
if(il<0)
{
negative=true;
num.clear();
num.push_back(-il);
}
else
{
negative=false;
num.clear();
num.push_back(il);
}
}
inline exnum operator-() const;
bool if_negative() const
{
return negative;
}
inline std::string format(num_type il,
std::string::size_type numw,
bool if_align=false,
std::string::size_type total=9)const;
private:
num_list num;
bool negative;
};
std::string exnum::format(exnum::num_type il,
std::string::size_type numw,
bool if_align,
std::string::size_type total) const
{
if (total%numw!=0)
{
total=9;
numw=3;
}
std::ostringstream iss;
iss<<il;
std::string tmp_str1(iss.str()),tmp_str2;
tmp_str2.reserve(total+total/3);
std::string::size_type hlen,need_to_output;
std::string::iterator iter=tmp_str1.begin();
hlen=tmp_str1.size() %numw;
need_to_output=9-tmp_str1.size();
if(if_align)
while(need_to_output>numw-hlen)
{
tmp_str2.append(",000");
if(need_to_output>numw-hlen+3) break;
need_to_output-=3;
}
if (if_align)
{
tmp_str2.push_back(',');
if (hlen!=0)
tmp_str2.append(std::string(numw-hlen,'0'));
}
if (hlen==0) hlen=numw;
tmp_str2.append(std::string(iter,iter+hlen));
iter+=hlen;
for (; (iter!=tmp_str1.end())&&(iter+numw<=tmp_str1.end()); iter+=numw)
{
tmp_str2.push_back(',');
tmp_str2.append(std::string(iter,iter+numw));
}
return tmp_str2;
}
exnum exnum::operator-() const
{
exnum tmp_e(*this);
tmp_e.negative=(negative?false:true);
return tmp_e;
}
#endif
exnum.cpp:
#include "exnum.h"
#include <string>
#include <sstream>
#define NUM_LENTH 3
#define BASE_NUMBER 1000000000
bool operator<(const exnum& e1,const exnum& e2)
{
if (e1.num.size()!=e2.num.size()) return e1.num.size()<e2.num.size();
exnum::num_list::const_iterator iter1(e1.num.begin()),iter2(e2.num.begin());
do
{
if ((*iter1)!=(*iter2)) return (*iter1)<(*iter2);
}
while (iter1!=e1.num.end());
return false;
}
std::istream& operator>>(std::istream& is,exnum& ien)
{
ien.num.clear();
if (is.peek()=='-')
{
ien.negative=true;
is.ignore();
}
std::string getin;
std::getline(is,getin);
exnum::num_type tmp_long;
std::string::iterator i;
i=getin.begin();
std::istringstream iss(std::string(i,i+(getin.size()%9)));
if (getin.size()%9!=0)
{
iss>>tmp_long;
ien.num.push_back(tmp_long);
}
i+=getin.size()%9;
iss.clear();
for (; 9<getin.end()-i; i+=9)
{
iss.str(std::string(i,i+9));
iss>>tmp_long;
ien.num.push_back(tmp_long);
iss.clear();
}
if (i!=getin.end())
{
iss.str(std::string(i,getin.end()));
iss>>tmp_long;
ien.num.push_back(tmp_long);
}
return is;
}
std::ostream& operator<<(std::ostream& os,const exnum& ien)
{
if (ien.num.empty()) return os;
if (ien.negative) os<<'-';
exnum::num_list::const_iterator i=ien.num.begin();
os<<ien.format(*i,NUM_LENTH);
for (++i; i!=ien.num.end(); ++i)
{
os<<ien.format(*i,NUM_LENTH,true);
}
return os;
}
exnum real_plus(const exnum& e1,const exnum& e2);
exnum real_mui(const exnum& e1,const exnum& e2);
exnum operator+(const exnum& e1,const exnum& e2)
{
if ((!e1.negative)&&(!e2.negative)) return real_plus(e1,e2);
if ((e1.negative)&&(e2.negative)) return -real_plus(e1,e2);
if (e1.negative) return real_mui(e2,e1);
else return real_mui(e1,e2);
}
exnum real_plus(const exnum& e1,const exnum& e2)
{
exnum tmp_e;
tmp_e.num.clear();
const exnum *e_small,*e_big;
if (e1.num.size()>e2.num.size())
{
e_small=&e2;
e_big=&e1;
}
else
{
e_small=&e1;
e_big=&e2;
}
exnum::num_list::const_reverse_iterator end1(e_small->num.rend()),end2(e_big->num.rend());
exnum::num_list::const_reverse_iterator i(e_big->num.rbegin()),j(e_small->num.rbegin());
exnum::num_type hlevel(0);
for (; j!=end1;)
{
tmp_e.num.push_front(*i + *j+hlevel);
if (*i+*j>BASE_NUMBER)
{
*tmp_e.num.begin()-=BASE_NUMBER;
hlevel=1;
}
else hlevel=0;
++i;
++j;
}
if (hlevel)
{
if (i==end2) tmp_e.num.push_front(1);
else tmp_e.num.push_front(1+*i++);
}
for (; i!=end2;)
{
tmp_e.num.push_front(*i++);
}
return tmp_e;
}
exnum operator-(const exnum& e1,const exnum& e2)
{
return e1+(-e2);
}
exnum real_mui(const exnum& e1,const exnum& e2)
{
if (e1<e2) return -real_mui(e2,e1);
exnum tmp_e(e1);
exnum::num_list::reverse_iterator iter1(tmp_e.num.rbegin());
exnum::num_list::const_reverse_iterator iter2(e2.num.rbegin());
for (; iter2!=e2.num.rend(); ++iter2)
{
(*iter1)-=(*iter2);
if(*iter1<0)
{
(*iter1)+=BASE_NUMBER;
(*++iter1)-=1;
}
else ++iter1;
}
tmp_e.negative=false;
return tmp_e;
}
exrenum.cpp:
#include "exrenum.h"
#include "exnum.h"
#include<string>
#include<sstream>
std::istream& operator>>(std::istream& is,exrenum& ienx)
{
if (is.peek()=='.') is.ignore();
std::string tmp_str;
std::getline(is,tmp_str);
ienx.renum.num.clear();
long tmp_long;
std::string::size_type hlen(9-(tmp_str.size()%9));
if (hlen==9) hlen=0;
tmp_str.append(hlen,'0');
std::string::iterator i(tmp_str.begin());
for (; i!=tmp_str.end(); i+=9)
{
std::istringstream(std::string(i,i+9))>>tmp_long;
ienx.renum.push_back(tmp_long);
}
if (ienx.renum.num.empty())
{
ienx.renum.num.push_back(0);
return is;
}
if (*ienx.renum.num.begin()==0) return is;
exnum::num_list::reverse_iterator ri=ienx.renum.num.rbegin();
for (; (*ri==0)&&(ri!=ienx.renum.num.rend()); ++ri) ienx.renum.num.pop_back();
return is;
}
std::string re_format(long il,bool head,bool tail)
{
std::string out_str(exnum().format(il,3,true));
std::string::size_type i=out_str.size()-1;
if (tail)
for (; i!=-1&&(out_str[i]=='0'||out_str[i]==','); --i);
++i;
if (tail) out_str.erase(i,out_str.size());
if (out_str.empty()) return "0";
if (head) return out_str.substr(1,i);
else return out_str.substr(0,i);
}
std::ostream& operator<<(std::ostream& os,const exrenum& inex)
{
if (inex.renum.num.size()==1)
{
os<<re_format(*(inex.renum.num.begin()),true,true);
return os;
}
exnum::num_list::const_iterator i=inex.renum.num.begin();
os<<re_format(*i++,true,false);
for (; i!=inex.renum.num.end(); ++i)
{
os<<re_format(*i,false,false);
}
--i;
os<<re_format(*i,false,true);
return os;
}
void in_row(exrenum& iex1,exrenum& iex2)
{
if (iex1.renum.num.size()==iex2.renum.num.size()) return;
exrenum *small,*big;
if (iex1.renum.num.size()<iex2.renum.num.size())
{
small=&iex1;
big=&iex2;
}
else
{
small=&iex2;
big=&iex1;
}
do
{
small->renum.num.push_back(0);
}
while (small->renum.num.size()<big->renum.num.size());
}
void astyle(exrenum& iex)
{
iex.h_level-=1;
exrenum tmp_e;
tmp_e.renum.num.resize(iex.renum.num.size(),0);
*tmp_e.renum.num.begin()=1000000000;
iex.renum=tmp_e.renum+iex.renum;
}
exrenum operator+(const exrenum& iex1t,const exrenum& iex2t)
{
exrenum iex1(iex1t),iex2(iex2t);
in_row(iex1,iex2);
exnum::num_list::size_type l(iex1.renum.num.size());
exrenum out_e;
out_e.renum=iex1.renum+iex2.renum;
if (out_e.renum.num.size()>l)
{
out_e.h_level=*out_e.renum.num.begin();
out_e.renum.num.pop_front();
}
if (iex1.renum.negative) out_e.h_level-=iex1.h_level;
else out_e.h_level+=iex1.h_level;
if (iex2.renum.negative) out_e.h_level-=iex2.h_level;
else out_e.h_level+=iex2.h_level;
if (out_e.renum.negative) astyle(out_e);
return out_e;
}
exrenum exrenum::operator-() const
{
exrenum tmp_e(*this);
tmp_e.h_level=-tmp_e.h_level;
tmp_e.renum.negative=true;
astyle(tmp_e);
return tmp_e;
}
exrenum operator-(const exrenum& iex1,const exrenum& iex2)
{
return iex1+(-iex2);
}
num.cpp:
#include"num.h"
#include<string>
void num::postion()
{
this->n=this->n+exnum(ex.h_level);
if(n<exnum(0))
{
n=n-exnum(1);
ex.renum.negative=true;
ex=-ex;
}
ex.h_level=0;
}
num operator+(const num& n1,const num& n2)
{
num tmp_n;
tmp_n.n=n1.n+n2.n;
tmp_n.ex=n1.ex+n2.ex;
tmp_n.postion();
return tmp_n;
}
num operator-(const num& n1,const num& n2)
{
num tmp_n;
tmp_n.n=n1.n-n2.n;
tmp_n.ex=n1.ex-n2.ex;
tmp_n.postion();
return tmp_n;
}
std::istream& operator>>(std::istream& is,num& in)
{
std::string tmp_s;
std::getline(is,tmp_s);
std::istringstream iss;
std::string::size_type i(0),len(tmp_s.size());
for(;(i!=tmp_s.size())&&(tmp_s[i]!='.');++i);
if(i!=0)
{
iss.str(tmp_s.substr(0,i));
iss>>in.n;
iss.clear();
}
if(i!=len)
{
iss.str(tmp_s.substr(i,len));
iss>>in.ex;
}
return is;
}

浙公网安备 33010602011771号