高精度问题,我改的自己写的那个高精度模版,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()); } } }