1 #include<iostream>
  2 #include<string>
  3 #include<cstring>
  4 using namespace std;
  5 const int M=400;
  6 const int BASE=10;
  7 //****************************************
  8 class BigInt
  9 {
 10     friend BigInt operator+(const BigInt &a,const BigInt &b);
 11     friend BigInt operator*(const BigInt &a,const BigInt &b);
 12     friend BigInt operator-(const BigInt &a,const BigInt &b);
 13     friend BigInt operator/(const BigInt &a,const BigInt &b);
 14     friend ostream& operator<<( ostream &os,BigInt &a);
 15     //friend power(BigInt &BASE,BigInt &n);
 16 private:
 17     static int pos;    
 18     //小数点的位置 pos存放小数点后第一位。比如:3456.123 pos存放6
 19     int sign;   //数的正负 1为正数,-1为负数,
 20     int before; // 小数点前的位数
 21     int after;  //小数点后的位数
 22     int data[M];
 23 //    BigInt NormalAdd(const BigInt &a,const BigInt &b);
 24     BigInt NormalAdd(const BigInt &a);// 不考虑符号加法运算 return this+a
 25     BigInt NormalSubtract( const BigInt & a); //要求this>a进行减法 ,且不考虑符号
 26 public:
 27     BigInt();
 28     BigInt( string str);
 29     static void SetPos(int m){pos=m;}
 30     int AbsCompare(const BigInt &a);
 31     int Compare(const BigInt &a); // this>a return 1 ;this<a return -1;this ==a reuturn 0;
 32     BigInt Add( BigInt &a);
 33     BigInt Subtract(BigInt &a);
 34     BigInt Mul(const BigInt &a);
 35 };
 36 //****************************************
 37 BigInt::BigInt()
 38 {
 39     memset(data,0,sizeof(data));
 40     after=0;
 41     sign=1;
 42     before=0;
 43 }
 44 //***********************************************************
 45 BigInt::BigInt( string str)
 46 {
 47     memset(data,0,sizeof(data));
 48     if(str[0]!='-')
 49         sign=1;
 50     else sign=-1;
 51     if(str[0]=='-' || str[0]=='+')
 52         str.erase(0,1);
 53     unsigned int loc=str.find('.',0);
 54     int len=str.length();
 55     if(loc==string::npos)
 56     {
 57         after=0;
 58         before=len;
 59         for(int i=len-1,j=pos;i>=0;--i,++j)
 60         {
 61             data[j]=str[i]-'0';
 62         }
 63     }
 64     else
 65     {
 66         for(int i=loc-1,j=pos;i>=0;--i,++j)
 67         {
 68             data[j]=str[i]-'0';
 69         }
 70         before=loc;
 71         for(int i=loc+1,j=pos-1;i<len;++i,--j)
 72         {
 73             data[j]=str[i]-'0';
 74         }
 75         after=len-loc-1;
 76     }
 77     while(after>0 && data[pos-after]==0)
 78         --after;
 79 
 80     while(before>0 && data[pos+before-1]==0)
 81         --before;
 82 }
 83 //***********************************************************
 84 //*********************************************************************
 85 BigInt BigInt::NormalAdd(const BigInt & a)
 86 {
 87     BigInt res;
 88     res.sign=sign;
 89     res.after=a.after>after ? a.after:after;
 90     int bef=a.before>before ? a.before: before;
 91     for(int i=pos-res.after; i<pos+bef; ++i)
 92     {
 93         res.data[i]+=data[i]+a.data[i];
 94         if(res.data[i]>=BASE)
 95         {
 96             res.data[i+1]+=res.data[i]/BASE;
 97             res.data[i]%=BASE;
 98         }
 99     }
100     while(res.data[pos+bef])
101     {
102         res.data[pos+bef+1]+=res.data[pos+bef]/BASE;
103         res.data[pos+bef]%=BASE;
104         ++bef;
105     }
106     res.before=bef;
107     while(res.after>0 && res.data[pos-res.after]==0)
108     {
109         --res.after;
110     }
111     return res;
112 }
113 //********************************************************
114 int BigInt::AbsCompare(const BigInt &a)
115 {
116     if(before>a.before) return 1;
117     else if(before<a.before) return -1;
118     else 
119     {
120         int t=after>a.after ? after: a.after;
121         t=pos-t;
122         for(int i=pos+before-1; i>=t; --i)
123         {
124             if(data[i]>a.data[i])
125                 return 1;
126             else if(data[i]<a.data[i])
127                 return -1;
128         }
129     }
130     return 0;
131 }
132 //*********************************************************
133 int BigInt::Compare(const BigInt &a)
134 {
135     if(sign>a.sign) return 1;
136     else if(sign<a.sign) return -1;
137     else return sign*AbsCompare(a);
138 }
139 //**********************************************************
140 BigInt BigInt::NormalSubtract( const BigInt  &a)
141 {
142     BigInt res;
143     res.after=after>a.after ? after: a.after;
144     for(int i=pos-res.after; i<pos+before; ++i)
145     {
146         res.data[i]=data[i]-a.data[i];
147     }
148     for(int i=pos-res.after; i<pos+before; ++i)
149     {
150         if(res.data[i]<0)
151         {
152             res.data[i]+=BASE;
153             res.data[i+1]-=1;
154         }
155     }
156     int bef=before;
157     while(bef)
158     {
159         if(res.data[pos+bef-1])
160             break;
161         --bef;
162     }
163     res.before=bef;
164     while(res.after>0 && res.data[pos-res.after]==0)
165     {
166         --res.after;
167     }
168     return res;
169 }
170 //*********************************************************
171 BigInt BigInt::Add( BigInt &a)
172 {
173     if(sign==a.sign)
174         return NormalAdd(a);
175     BigInt res;
176     if(sign>a.sign)
177     {
178         if(AbsCompare(a)>=0)  
179         {
180             res=NormalSubtract(a);
181             res.sign=1;
182         }
183         else
184         {
185             res=a.NormalSubtract(*this);
186             res.sign=-1;
187         }
188     }
189     else if(sign<a.sign)
190     {
191         if(AbsCompare(a)>0)
192         {
193             res=NormalSubtract(a);
194             res.sign=-1;
195         }
196         else 
197         {
198             res=a.NormalSubtract(*this);
199             res.sign=1;
200         }
201     }
202     return res;
203 }
204 //********************************************************
205 BigInt BigInt::Subtract(BigInt &a)
206 {
207     if(sign!=a.sign)
208     {
209         return NormalAdd(a);
210     }
211     BigInt res;
212     if(sign==1)
213     {
214         if(AbsCompare(a)>=0)
215         {
216             res=NormalSubtract(a);
217             res.sign=1;
218         }
219         else 
220         {
221             res=a.NormalSubtract(*this);
222             res.sign=-1;
223         }
224     }
225     else if(sign==-1)
226     {
227         if(AbsCompare(a)>0)
228         {
229             res=NormalSubtract(a);
230             res.sign=-1;
231         }
232         else
233         {
234             res=a.NormalSubtract(*this);
235             res.sign=1;
236         }
237     }
238     return res;
239 }
240 //********************************************************
241 BigInt BigInt::Mul(const BigInt &a)
242 {
243     BigInt res;
244     if(sign!=a.sign)  res.sign=-1;
245     else res.sign=1;
246     int len=before+after;
247     int alen=a.before+a.after;
248     for(int i=0,j=pos-after; i<len; ++i,++j)   //计算
249     {
250         for(int k=0,t=a.pos-a.after; k<alen; ++k,++t)
251         {
252             res.data[i+k]+=data[j]*a.data[t];
253         }
254     }
255     for(int i=0;i<len+alen;++i)  //进位
256     {
257         if(res.data[i]>=BASE)
258         {
259             res.data[i+1]+=res.data[i]/BASE;
260             res.data[i]%=BASE;
261         }
262     }
263     int shift=pos-after-a.after;                //计算应该移动的位数
264     for(int i=len+alen; i>=0--i)
265     {
266         res.data[i+shift]=res.data[i];
267         res.data[i]=0;
268     }
269     int i=0;
270     while(i<pos)
271     {
272         if(res.data[i]>0break;
273         ++i;
274     }
275     res.after=pos-i;
276     int bef=alen+len+shift;
277     if(res.data[bef]>0)
278     {
279         while(res.data[bef])
280         {
281             res.data[bef+1]=res.data[bef]/BASE;
282             res.data[bef]%=BASE;
283             ++bef;
284         }
285         res.before=bef-pos;
286     }
287     else 
288     {
289         while(bef>=pos)
290         {
291             if(res.data[bef]>0break;
292             --bef;
293         }
294         res.before=bef-pos+1;
295     }
296     return res;
297 }
298 //********************************************************
299 ostream & operator<<(ostream &os,BigInt &a)
300 {
301     if(a.sign==-1)
302         os<<'-';
303     for(int i=a.before+a.pos-1; i>=a.pos; --i)
304         os<<a.data[i];
305     if(a.after>0)
306     {
307         os<<'.';
308         for(int i=a.pos-1; i>=a.pos-a.after; --i)
309             os<<a.data[i];
310     }
311     if(a.after==0 && a.before==0)
312         os<<'0';
313     return os;
314 }
315 //********************************************************
316 int BigInt::pos=200;
317 
    高精度应该不是什么陌生的东西了,以前觉得这个东西挺高深的,其实明白了也就没什么了。我们知道对于int只能保存32位的数,long long也不过能保存64位的,若是要更大的数就只能自己动手写了,大概就是模拟笔算而已。

    对于一个大数怎么来表示我们先约定一个格式。用一个int类型的sign来表示符号位,正数为1,负数为-1。用一个int数组data[]来存储数据,用一个int类型的数字pos来表示小数点所在的地方,这个数字对于所有的BigInt应该是相同的所以用静态变量。before表示小数点前面有几位数字,after表示小数点后面有几位数字。比如说:-356.5672  sign为-1,before为3,after为4。当然可以用其他方法表示,只是我觉得用着这样的表示方法有很多有点。
    AbsCompare()为其绝对值的比较。
    NormalSubtract( const BigInt  &a)为不考虑符号的减法运算要求|this|>|a|,返回值为|this|-|a|,比如:-100-(-50)返回值为50。

    对于加法Add运算可分为,正数+正数,负数+正数,正数+负数,负数+负数,不考虑符号位的加法称为NormalAdd(),对于正数+正数,负数+负数,可以用NormalAdd(),然后考虑符号为就行了。比如说:(-123)+(-456) 可以认为是123+456然后再为其加符号位-1,即-(123+456)。而对于正数+负数,负数+正数,其实是普通的减法。比如说:567+(-123),其实是567-123; -567 +123 亦是如此。

    对于减法Subtract运算亦可分为:正数-正数,正数-负数,负数-正数,负数-负数。正数-负数其实是加法运算,例如: 100-(-200)==100+200;负数-正数也可看成加法运算,然后再考虑符号问题,例如:-100 - 200==-(100+200);正数-正数要分开考虑:减数的绝对值大于被减数的绝对值,被减数的绝对值大于减数的绝对值,然后在进行Norsubtract运算,之后考虑符号为就可以了。例如:500-200==+(300),200-500==-(500-200)。负数-负数同正数-正数相同。

    乘法Mul则相对简单一些,同号得正,异号得负。然后考虑正数的乘法运算,模仿笔算乘法就行了。
   
    除法其实是减法,逐次相减就可以了,代码里没有写。