题目:http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid=2§ionid=3&problemid=2
求一个大数(小数或整数)的n 次幂。
思路:
1、大数乘法
首先,将两个操作数逆转存放。
然后,将第i位和第j位相乘的结果累加存入得数的第i+j位。
再处理进位,把进位加到下一位。
最后确定得数的位数。一个A位数和一个B位数相乘的结果最长为A+B位。从得数的A+B位开始,判断是否为0,若为0 ,则得数长度减1.。
Number mul(Number A,Number B)
{
Number C;
int carry;
for(int i = 0;i < A.len;i++)
for(int j = 0;j < B.len;j++)
{
C.num[i + j] += (A.num[i] * B.num[j]);
}
int len = A.len + B.len ;
carry = 0;
for(int i = 0;i < len;i++)
{
C.num[i] += carry;
if(C.num[i] > 9)
{
carry = C.num[i] / 10;
C.num[i] = C.num[i] % 10;
}
else carry = 0;
}
while(C.num[len - 1] == 0)
{
len--;
}
C.len = len;
return C;
}
整数的n次幂必定为整数,小数的N次幂则为小数(0次幂除外),所以要确定得数小数点位置。
一个有m位小数的数的n次幂,得数有m*n位小数。
消除后置0
在处理输入数时,先判断是否存在小数点。若存在,删除小数点最后的0。
然后求出小数点后的数字位数,即小数的位数。
在完成乘法后,可能需要在小数点后补0
根据得数的长度与得数小数位数比较,
若小数位数 >= 得数长度,小数点在最前面,小数点后需要补小数点位数 - 得数长度个0.
否则,则在得数中的小数点位置插入小数点。
#include <stdio.h>
#include <string.h>
struct Number
{
int num[200];
int len;
Number()
{
memset(num,0,sizeof(num));
len = 0;
}
};
Number mul(Number A,Number B)
{
Number C;
int carry;
for(int i = 0;i < A.len;i++)
for(int j = 0;j < B.len;j++)
{
C.num[i + j] += (A.num[i] * B.num[j]);
}
int len = A.len + B.len ;
carry = 0;
for(int i = 0;i < len;i++)
{
C.num[i] += carry;
if(C.num[i] > 9)
{
carry = C.num[i] / 10;
C.num[i] = C.num[i] % 10;
}
else carry = 0;
}
while(C.num[len - 1] == 0)
{
len--;
}
C.len = len;
return C;
}
int main()
{
int n,len;
char R[200];
Number A;
Number Ans;
int decimalPoint;
bool decimalPointFlag;
while(scanf("%s %d",R,&n) != EOF)
{
len = strlen(R);
decimalPoint = 0;
decimalPointFlag = false;
A.len = 0;
for(int i = 0;i < len;i++) //是否为小数
if(R[i] == '.')
decimalPointFlag = true;
if(decimalPointFlag)
while(R[len -1] == '0') //去除小数点后最后多余的0
len--;
for(int i = len - 1; i >= 0 ; i--)
{
if(R[i] == '.')
decimalPoint = len - i - 1; //小数点后数字的位数
else A.num[A.len++] = R[i] - '0';
}
Ans.num[0] = 1;
Ans.len = 1;
decimalPoint *= n;
while(n--)
{
Ans = mul(Ans,A);
}
if(Ans.len == 0)
printf("%c", '0');
if(decimalPoint >= Ans.len) //小数点位数 >= 得数长度时,要在最前面补小数点
{
printf("%c", '.');
for(int i = 0;i < decimalPoint - Ans.len;i++) //得数长度小于小数点位数时,要补0
printf("%c", '0');
}
for(int i = Ans.len - 1;i >= 0;i--)
{
printf("%d", Ans.num[i]);
if(decimalPoint != 0 && i == decimalPoint)
printf("%c", '.');
}
printf("\n");
}
return 0;
}