高精度问题,我改的自己写的那个高精度模版,c++来写高精度就是麻烦,还要考虑一大堆特殊情况。
我用的一些个测试数据:
000 00
0
00001.1000 2.9
4
00001.1110 3.333000
4.444
99.2 0.8
100
主要的特殊情况就是前导0和后导0,以及全部都是0的情况。
我的思路就是:
以009.200和00.8 为例,
1)首先把小数转化成小数部分位数相同的数,转化成009.200和00.800;
2)然后去掉小数点,009200和00800
3)再大整数相加调用add(),相加得010000
4)然后在输出ans字符数组的时候忽略前面的所有0和小数点后的某位之后全是零的情况,以及在输出的时候注意什么时候输出小数点。
/*任务:高精度,计算大数加大数
*
*参数:乘法函数mul参数为 被加数a[],加数b[],保存最终结果的ans数组
*结果:ans数组中ans[0]为最高位,以此类推
*/
#include <iostream>
#include <string.h>
#define MAX 10000
using namespace std;
int max(int a,int b){
if(a>b)return a;
else return b;
}
void delete_point(char*a){
int len=strlen(a);
int i;
for(i=0;i<len;i++){
if(a[i]=='.') break;
}
if(i<len-1){
for(int j=i;j<len-1;j++)
a[j]=a[j+1];
a[len-1]=0;
}
}
int add(char a[],char b[],char ans[]) {
int i,j,s,len,c=0;
int temp_a[MAX],temp_b[MAX],temp_ans[MAX];
memset(ans,0,sizeof(ans));
memset(temp_a,0,sizeof(temp_a));
memset(temp_b,0,sizeof(temp_b));
memset(temp_ans,0,sizeof(temp_ans));
len=max(strlen(a),strlen(b));
for (i=0;i<strlen(a);i++)
temp_a[strlen(a)-i-1]=a[i]-'0';
for (i=0;i<strlen(b);i++)
temp_b[strlen(b)-i-1]=b[i]-'0';
for(j=0;j<len;j++){
s=temp_a[j]+temp_b[j]+c;
temp_ans[j]=s%10;
c=s/10;
}
if(c) temp_ans[len++]=c;
for (i=0;i<len;i++)
ans[len-1-i]=temp_ans[i]+'0';
ans[len]='\0';
return len;
}
int main()
{
char a[MAX],b[MAX],ans[MAX];
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
while(cin>>a>>b){
int len_a=strlen(a);
int len_b=strlen(b);
int len_a_1=0,len_a_2=0;
int len_b_1=0,len_b_2=0;
for(int i=0;i<len_a;i++){
if(a[i]!='.') len_a_1++;
else {
len_a_2=len_a-len_a_1-1;
break;
}
}
for(int i=0;i<len_b;i++){
if(b[i]!='.') len_b_1++;
else {
len_b_2=len_b-len_b_1-1;
break;
}
}
//cout<<"差"<<abs(len_b_2-len_a_2)<<endl;
if(len_b_2>len_a_2){
for(int i=len_a;i<len_a+len_b_2-len_a_2;i++)
a[i]='0';
len_a+=len_b_2-len_a_2;
}
else if(len_b_2<len_a_2){
for(int i=len_b;i<len_b+len_a_2-len_b_2;i++)
b[i]='0';
len_b+=len_a_2-len_b_2;
}
//cout<<a<<endl;
//cout<<b<<endl;
//去除小数点
delete_point(a);
delete_point(b);
//cout<<a<<endl;
//cout<<b<<endl;
int len_ans=add(a,b,ans);
//cout<<ans<<endl;
int flag_point=len_ans-max(len_a_2,len_b_2);
int flag_int=1; //标志是否是整数 ,1代表整数
int flag_zero_front=1; //忽略前导零时使用 ,1表示全部为0,0表示最终结果不是零
int flag_zero_behand;//忽略后导零时使用 ,1表示后面全部为0,0表示后面不全是0
int flag_zero_all=1;
for(int i=flag_point;i<len_ans;i++)
if(ans[i]!='0') flag_int=0;
for(int i=0;i<len_ans;i++)
if(ans[i]!='0') flag_zero_all=0;
if(flag_zero_all==1) {
cout<<"0"<<endl;
continue;
}
for(int i=0;i<len_ans;i++){
flag_zero_behand=1;
if(i==flag_point-1) flag_zero_front=0;
if(i==flag_point&&flag_int==1)break;
if(i==flag_point) cout<<'.';
if(flag_zero_front==0||ans[i]!='0'){
for(int j=i;j>=flag_point&&j<len_ans;j++){
if(ans[j]!='0') flag_zero_behand=0;
}
if(i>=flag_point&&flag_zero_behand==1) break;
cout<<ans[i];
flag_zero_front=0;
}
}
cout<<endl;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
}
return 0;
}
java秒过
import java.io.*;
import java.util.*;
import java.math.*;
public class Main {
public static void main(String[] args) {
Scanner cin=new Scanner(System.in);
BigDecimal a=new BigDecimal(0);
BigDecimal b=new BigDecimal(0);
while(cin.hasNext()){
a=cin.nextBigDecimal();
b=cin.nextBigDecimal();
System.out.println(a.add(b).stripTrailingZeros().toPlainString());
}
}
}