http://poj.org/problem?id=1001
Description
Input
Output
Sample Input
95.123 12 0.4321 20 5.1234 15 6.7592 9 98.999 10 1.0100 12
Sample Output
548815620517731830194541.899025343415715973535967221869852721 .00000005148554641076956121994511276767154838481760200726351203835429763013462401 43992025569.928573701266488041146654993318703707511666295476720493953024 29448126.764121021618164430206909037173276672 90429072743629540498.107596019456651774561044010001 1.126825030131969720661201
#include<iostream> #include<string.h> #include<cstdio> using namespace std; #define size 1000 //大数位数 void mult(char * A, char * B, char * ans); char a[size + 1]; char ans[size * size + 1]; int main(void) { int b; while (cin >> a >> b) { memset(ans, '\0', sizeof(ans)); ans[0] = '1'; ans[1] = '\0'; for (int i = 1; i <= b; i++) { mult(a, ans, ans); } cout << ans << endl; } return 0; } void mult(char * A, char * B, char * ans) { //printf("\nA %s\nB %s\nans %s\n",A,B,ans); int i, j, k; int fract; //总小数个数 int dot = -1; //小数点位置 for (k = 0; A[k] != '\0'; k++) { if (A[k] == '.') { dot = k; } } //printf("a的小数点位置 %d\n",dot); int lena = k; if (dot == -1) { fract = 0; } else { fract = lena - dot - 1; } //printf("小数的位数 %d\n",fract); dot = -1; for (k = 0; B[k] != '\0'; k++) { if (B[k] == '.') { dot = k; } } //printf("B的小数点位置 %d\n",dot); int lenb = k; if (dot == -1) { fract += 0; } else { fract += (lenb - dot - 1); //总小数个数 } //printf("a+b的总小数个数 %d\n",fract); int a[size + 1] = {0}; int b[size + 1] = {0}; int pa = 0, pb = 0; /*倒序 将字符串数组变成整数数组*/ for (i = lena - 1; i >= 0; i--) { if (A[i] == '.') //暂时删除小数点 { continue; } a[pa++] = A[i] - '0'; //printf("%d",a[pa-1]); } //printf("\tA\n"); for (j = lenb - 1; j >= 0; j--) { if (B[j] == '.') //暂时删除小数点 { continue; } b[pb++] = B[j] - '0'; //printf("%d",b[pb-1]); } //printf("\tB\n"); int c[2 * size + 1] = {0}; int lenc; for (pb = 0; pb < lenb; pb++) { int w = 0; //低位到高位的进位 for (pa = 0; pa <= lena; pa++) // = 为了处理最后的进位 { int temp = a[pa] * b[pb] + w; w = temp / 10; temp = (c[pa + pb] += temp % 10); c[lenc = pa + pb] = temp % 10; w += temp / 10; } } /*倒序,得到没有小数点的ans*/ for (pa = 0, pb = lenc; pb >= 0; pb--) { ans[pa++] = c[pb] + '0'; } //puts(ans); ans[pa] = '\0'; lena = pa; /*插入小数点*/ bool flag = true; //标记是否需要删除小数末尾的0 if (fract == 0) //小数位数为0,无需插入小数点 { flag = false; } else if (fract < lena) //小数位数小于ans长度,在ans内部插入小数点 { ans[lena + 1] = '\0'; for (i = 0, pa = lena; pa > 0; pa--, i++) { if (i == fract) { ans[pa] = '.'; break; } else { ans[pa] = ans[pa - 1]; } } } else //小数位数大于等于ans长度,在ans前面恰当位置插入小数点 { char temp[size + 1]; strcpy(temp, ans); ans[0] = '0'; ans[1] = '.'; for (int i = 0; i < fract - lena; i++) //补充0 { ans[i + 2] = '0'; } for (j = i, pa = 0; pa < lena; pa++) { ans[j++] = temp[pa]; } ans[j] = '\0'; } /*删除ans小数末尾的0*/ if (flag) { lena = strlen(ans); pa = lena - 1; while (ans[pa] == '0') { ans[pa--] = '\0'; } if (ans[pa] == '.') //小数全为0 { ans[pa--] = '\0'; } } /*删除ans整数开头的0,但至少保留1个0*/ pa = 0; while (ans[pa] == '0') //寻找ans开头第一个不为0的位置 { pa++; } if (ans[pa] == '\0') //没有小数 { ans[0] = '0'; ans[1] = '\0'; } else //有小数 { for (i = 0; ans[pa] != '\0'; i++, pa++) { ans[i] = ans[pa]; } ans[i] = '\0'; } return; }