您的位置:首页 > 其它

poj1001_BigNumMultipy

2014-04-14 14:47 246 查看
对于高精度数注意:

1.数据存储方式:数组和字符串

2.正确的运算过程

+、-:保持进位借位,用ncarry记录

*:c[i+j]+=a[i]*b[j]

/:用减法迭代a[1..n]-b[1..n],每次c[1..n]++

3.正确的输出表示,对于小数点的处理

这是大数幂次方

#include <iostream>
#include <stdlib.h>
#include <cstring>
#define SIZE 1000
using namespace std;

/*1.保证运算正确
2.获得数据并去掉小数点,依据幂指数确定小数点位数
3.调用高精度乘法获得整数结果
4.补上小数点
5.若小数点的总位数大于结果长度,应先输出点.*/

//运算前去掉小数点后多余的0,point 记录小数点后的位数
void preprocess(char s[],int& point)
{
int len = strlen(s);
char tmp[SIZE];
int i = len - 1;
//小数点不会出现在第一位
while(i>0)
{
if(s[i]=='.') break;
i--;
}
//小数点被忽略了
if(i>0)
{
while(s[len-1]=='0') len--;
point = len-i-1;
int j=0;
for(i=0;i<len;i++)
if(s[i]!='.')
s[j++]=s[i];
s[j]=0;
}
}
//将数组逆置
void reverse(char t[],int n)
{
int i=0,j=n-1;
while(i<j)
{
char tmp = t[i];
t[i] = t[j];
t[j] = tmp;
i++,j--;
}
}

void check(int tmp[],int n,char result[])
{
int i,j,k=0;
//按十进制表示
for(i=0;i<n;i++)
{
tmp[i+1]+=tmp[i]/10;
tmp[i]=tmp[i]%10;
}
//reverse and change to char array
while(tmp[i]==0) i--;
for(j=i;j>=0;j--)
result[k++]=tmp[j]+'0';
//添加结束标志位
result[k]=0;
}
//数组乘法
void mul(char s[],char t[],char result[])
{
int ls = strlen(s);
int lt = strlen(t);
reverse(s,ls);
reverse(t,lt);
int tmp[SIZE*2]={0};
int i,j,k;
int a=0;
for(i=0;i<ls;i++)
for(j=0;j<lt;j++)
tmp[i+j]+=(int)(s[i]-'0')*(int)(t[j]-'0');
check(tmp,i+j,result);
}
//添加小数点
void show(int point,char result[])
{
int len = strlen(result);
int tmp[SIZE*2];

//若为0.00..等的情况
if(point>=len)
cout<<".";

while(point>len)
{
cout<<"0";
point--;
}

for(int i=0;i<len;i++)
{
cout<<result[i];
if(i==len-1-point&&point!=0)
cout<<".";
}
cout<<endl;
}
int main()
{
char s[SIZE];
int n;
while(cin>>s>>n)
{
if(n==0)
{	cout<<"1"<<endl;
continue; }

int i,point=0;
preprocess(s,point);
char result[SIZE*2];
char tmp[SIZE];
strcpy(result,s);
strcpy(tmp,s);
//n次乘以自己,阶乘
for(i=0;i<n-1;i++)
{
strcpy(s,tmp);
mul(s,result,result);
}
show(point*n,result);
}

return 0;
}
转自:网上poj1001讲解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: