HDU 1063 Exponentiation

本文深入探讨了高精度运算中处理小数点位置及末尾0的重要细节,通过实例展示了如何正确计算并输出结果,避免常见的WA错误。通过字符串转换为高精度数、特殊条件处理及复杂乘法运算,确保算法的准确性和效率。

题目不难,一个高精度即可,但细节特别重要,特别是对于0的处理和小数点位置的确定特别重要,因此在高精度算完之后,需要【同时】确定小数点的正确位置和末尾0的处理,这道题的细节十分重要!!!我因此WA了3次。。


#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 200
using namespace std;

typedef struct node{
	char num[MAXN];
	int len; 
}bign;
int dot;

bign stringToBign(char *s)
{
	int slen=strlen(s);
	int p=-1,i=0;
	bign g;
	memset(g.num,0,sizeof(g.num));
	while(1){
		if(s[i]=='.')		p=i;
		else if(s[i]!='0')	break;
		i++;
	}
	int j=0;
	for(;i<slen;i++){
		if(s[i]=='.')		p=i;
		else				g.num[j++]=s[i];
	}
	strrev(g.num);
	for(i=0;i<j;i++){
		g.num[i]-='0';
	}	
	if(p==-1)	dot=0;
	else		dot=slen-1-p;
	g.len=j;	
	return g;
}
bign times(bign a,bign b)
{
	bign s;
	int t=0,i=0,j=0;
	memset(s.num,0,sizeof(s.num));
	while(i<a.len){
		j=0;
		while(j<b.len||t!=0){
			t=a.num[i]*b.num[j]+s.num[i+j]+t;
			s.num[j+i]=t%10;
			t/=10;
			j++;
		}
		i++;
	}
	s.len=j+i-1;
	return s;
}
int main()
{
	bign base,ans;
	char s[10];
	int n;
	while(scanf("%s%d",s,&n)==2){
		base=stringToBign(s);//字符串转换成bign,同时去除前导0和小数点,保留末尾的0,当成大整数直接高精
		if(n==0)		printf("1\n"); //特判0可以方便一点
		else{
			if(n==1)	ans=base;
			else{
				ans=times(base,base);
				for(int i=3;i<=n;i++)	ans=times(ans,base);//高精度乘法
			}
			dot*=n;
			int d=dot-ans.len;//判断小数点的位置
			if(ans.len<1)	printf("0\n");//答案0的处理
			else{
				int lo=0;
				char op[MAXN+10]={0};
				if(d>=0){确定小数点的位置
					sprintf(op+(lo++),".");//纯小数
					for(int i=0;i<d;i++)			sprintf(op+(lo++),"0");
					for(int i=ans.len-1;i>=0;i--)	sprintf(op+(lo++),"%d",ans.num[i]);
				}else{
					d*=-1;
					int j=ans.len;
					
					 //非纯小数
					for(int i=0;i<d;i++){
						sprintf(op+(lo++),"%d",ans.num[--j]);
					}
					sprintf(op+(lo++),".");
					j--;
					while(j>=0){
						sprintf(op+(lo++),"%d",ans.num[j--]);
					}
				} 
				
				int i=strlen(op);
				while(op[--i]=='0');//去除末尾0
				if(op[i]=='.')	i--;
				op[i+1]=0;
				printf("%s\n",op);
				
			}
		}
		
	}
	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值