2951:浮点数求高精度幂

思路

1.将浮点数,记录小数点位置,并去除小数点变成整数(例如99.99===>9999,小数点位置=2)
2.使用快速幂算法 计算整数的幂

void mul(int *a,int *b){
	int temp,c[250];
	memset(c,0,sizeof(c));
	for(int i=0;i<125;i++){
		int nC=0;
		for(int j=0;j<125;j++){
			temp=c[i+j]+a[j]*b[i]+nC;
			nC=temp/10;
			c[i+j]=temp%10;
		}
	}
	memcpy(a,c,sizeof(c));
}

main
{
......
while(n>0){
			if(n&1)
				mul(ans,base);
			mul(base,base);
			n>>=1;
		}
.....
}

3.处理结果,将小数点放进去

{
	//输入有小数点
					{
	                //先把小数点加进结果数组
	                //找小数点后面第一个不为0的数的位置
	                //如果这个位置==小数点位置,就是说算出来是整数,位置+1 不输出小数点
	                }
	//无小数点
}
	j=0;
		
		int count=0;//记录小数点后第一个不为0的位置 ,无小数点则为0
		 
		if(dot!=0){//有小数点 
			for(int i=0;i<150;i++){	
				if(dot!=i){
					astr[j] = ans[i]+'0';
					j++;
				}
				else if(dot==i){
					astr[j]= '.';
					j++;
					astr[j]= ans[i]+'0';
					j++;
				}
			}
			//找小数点后面第一个不为0的数的位置
			for(int k=0;k<124;k++){
				if(astr[k]!='0'){
					count=k;
					break;
				}
			}
			//小数点位置等于count,就是小数点后面没有有效数字,+1不输出小数点 
			if(count==dot)
				count++; 
		}
		else{//无小数点 
			for(int i=0;i<150;i++){
				astr[j++] = ans[i]+'0';
			}
		}

4.输出结果

AC代码

//最多125位,小数点最多75位 
//将浮点数化成整数,并计算出扩大了多少倍
//整数部分高精度快速幂, 扩大倍数n*log10()直接计算出小数点位置
 
#include<stdio.h>
#include<memory.h>
#include<string.h>

void mul(int *a,int *b){
	int temp,c[250];
	memset(c,0,sizeof(c));
	for(int i=0;i<125;i++){
		int nC=0;
		for(int j=0;j<125;j++){
			temp=c[i+j]+a[j]*b[i]+nC;
			nC=temp/10;
			c[i+j]=temp%10;
		}
	}
	memcpy(a,c,sizeof(c));
}

int main(){
	char str[8];
	char astr[150];
	int n,len,dot;
	int ans[250];
	int base[250];
	while(scanf("%s",str)!=EOF){
		memset(ans,0,sizeof(ans));
		memset(base,0,sizeof(base));
		memset(astr,'0',sizeof(astr));
//
		scanf("%d",&n);
		len=strlen(str);
		ans[0]=1;
		int j=0;
		dot=0;
		for(int i=len-1;i>=0;i--){ 
			//找到小数点的位置 
			if(str[i]=='.')
				dot=len-i-1;
			//整数放入base 
			if(str[i]!='.')
				base[j++]=(str[i]-'0');
		} 
		
		dot *=n;
		
		//大幂幂
		while(n>0){
			if(n&1)
				mul(ans,base);
			mul(base,base);
			n>>=1;
		}
		
		//处理结果
		//数和点都放到字符串数组
		j=0;
		
		int count=0;//记录小数点后第一个不为0的位置 ,无小数点则为0
		 
		if(dot!=0){//有小数点 
			for(int i=0;i<150;i++){	
				if(dot!=i){
					astr[j] = ans[i]+'0';
					j++;
				}
				else if(dot==i){
					astr[j]= '.';
					j++;
					astr[j]= ans[i]+'0';
					j++;
				}
			}
			//找 小数点后的零 
			for(int k=0;k<124;k++){
				if(astr[k]!='0'){
					count=k;
					break;
				}
			}
			//小数点位置等于count,就是小数点后面没有有效数字,+1不输出小数点 
			if(count==dot)
				count++; 
		}
		else{//无小数点 
			for(int i=0;i<150;i++){
				astr[j++] = ans[i]+'0';
			}
		}
		
		
		
		//输出 
		int flag=0;
		for(int i=124;i>=count;i--){ 
			if(flag!=0)
				printf("%c",astr[i]);
			else if(astr[i]!='0'){
					printf("%c",astr[i]);
					flag=1;
			}
		}
		printf("\n"); 
}	
} 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值