高精度問題,我改的自己寫的那個高精度模版,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 10000using 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());}}}