算法学习——1.高精度求幂Exponentiation

Exponentiation

Description

Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems. 

This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25.

Input

The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9.

Output

The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer.

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

求幂

描述

涉及计算非常大的值和精度的精确值的问题是常见的。例如,对许多计算机系统来说,国债的计算是一项繁重的工作。

此问题要求您编写程序以计算R^n的精确值,其中R是实数(0.0 <R <99.999),n是整数,0 <n <= 25。

输入

输入将由一组R和n的值组成。 R值将占据第1列到第6列,n值将在第8列和第9列中。

输出

每一行输入计算得到一行输出,给出R^n的确切值。在输出中应该抑制前导零。不重要的尾随零不能打印。如果结果是整数,不要打印小数点。

 

思想

由于double,long等类型存储的数据大小受限,故该题不能直接采用math中的函数。要根据我们手动计算的方法来考虑。由于数据太大,需要采用数组来装存储。申请一个空间为250的一维数组int result[250],里面存放每次相乘得到的结果。用一个字符数组装R,比如计算95.120^12时,将95.120放在一个数组里。r[0]='9',r[1]='5',r[2]='.',r[3]='1',r[4]='2',r[5]='0',后面进行处理:将小数点和小数点后面无效的’0‘用-1替换,便于后面将有效的计算位提取出来,比如这里得到的是int R=9512。然后将它赋值给最初的result[250],我是放在数组的最后面,即result[246] = 9, result[247] = 5, result[248] = 1, result[249] = 2, 这样符合手工计算的习惯。每一位(比如result[249] )分别乘以R(即9512),得到一个大数medi,medi模10后放在新的result[249] 的位置,medi除以10存储在临时变量tp里,这是留给下一位(result[248])计算时的进位result[248]乘以R后加上进位,又可以做模10和除以10的操作。直到result里有效的部分全都做了这样的操作,更新了result[250]数组。重复上面的过程n次,就得到了结果。

ps:处理过程中,要记录小数点的位置,以便确定输出中的小数点该在什么位置。还要注意一些特殊取值的处理,比如000000,10.000等。

代码如下:

#include <string>
#include <iostream>
#include <sstream>
using namespace std;

int main() {

	int n;//幂数
	string s;// 输入的前六位
	while(cin>>s>>n) {
		int result[250]= {0};//存储结果
		char temp[6];//将输入的前六位转为数组
		int p=0,R=0;//P表示原始数据小数点后的有效位个数 ,R是不含小数点的数值
		int count = 0;

		for(int i = 0; i < 6 ; i++) { //找到小数点的位置
			if(s[i] == '.') {
				temp[i] = -1;//小数点标记成负一
				p =  5-i;//小数点后有几位
				continue;//把小数点标记
			}
			temp[i] = s[i];
		}
		//p=0说明没有小数点

		//倒着处理一次,把小数点后的无效0标记为-1,
		if( p != 0) {
			for(int i =5 ; i>=0 ; i--) {
				if(temp[i] != '0') {
					//除去无效0后,P的值
					p = p-(5-i);
					break;
				}
				temp[i] = -1;
			}

		}
		//	cout<<" P为"<<p<<endl;
		for(int i = 0; i < 6; i++) {
			if(temp[i] != -1) {

				R = R*10+(s[i]-'0');  //将输入输入的 R 提取出来
			}
		}
		//cout <<" R为"<<R<<endl;

		//把R整数转化成字符数组
		string med;
		stringstream ss;
		ss<<R;
		med = ss.str();
		int len = med.length();		//数据长度
		int m = p*n; //输出值里面小数点后应该有几位有效数
		int k=1;
		//cout <<" len为"<<len<<endl;

		for(int i = 1 ; i <= len ; i++) {
			result[249 - len+i] = med[i-1]-'0';//将初始值存入result,此时为R的有效值
		}


		while(n > 1) {
			int j = 249;
			int tp = 0;//临时存储
			++k;
			for(int j = 249; j >= 0 ; j--) {

				//每一个有效位位都乘以R值
				if( j <= 250 - k*len  && tp == 0 ) {//这里是为了满足100*100类似的末尾为0的情况
					continue;
				}
				int medi = result[j]*R+tp;
				tp = medi / 10;
				result[j] = medi % 10;
				//	cout<<j<<"位置的值是 "<< result[j] <<endl;

			}

			n--;
		}
		//开始处理输出,P是初始值小数点后面数据个数,n是幂数

		for(int i = 0 ; i<250 ; i++) {
			if(result[i] != 0) {
				count = 250 - i;//result里的有效数字
				break;
			}

		}

		if( m >= count) { //说明结果小于1
			if(count == 0) {//当结果为0
				cout<<0<<endl;
				continue;
			}
			cout << ".";
			for(int i = 250 - m; i < 250; i++) {
				cout << result[i];

			}
		} else { //结果大于1
			for(int i = 250 - count; i < 250; i++) {
				cout << result[i];
				if(i == 249 - m && i!=249) {
					cout << ".";
				}
			}
		}
		cout<<endl;
	}
	return 0;
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Problems involving the computation of exact values of very large magnitude and precision are common. For example, the computation of the national debt is a taxing experience for many computer systems. This problem requires that you write a program to compute the exact value of Rn where R is a real number ( 0.0 < R < 99.999 ) and n is an integer such that 0 < n <= 25. 输入说明 The input will consist of a set of pairs of values for R and n. The R value will occupy columns 1 through 6, and the n value will be in columns 8 and 9. 输出说明 The output will consist of one line for each line of input giving the exact value of R^n. Leading zeros should be suppressed in the output. Insignificant trailing zeros must not be printed. Don't print the decimal point if the result is an integer. 输入样例 95.123 12 0.4321 20 5.1234 15 6.7592 9 98.999 10 1.0100 12 输出样例 548815620517731830194541.899025343415715973535967221869852721 .00000005148554641076956121994511276767154838481760200726351203835429763013462401 43992025569.928573701266488041146654993318703707511666295476720493953024 29448126.764121021618164430206909037173276672 90429072743629540498.107596019456651774561044010001 1.126825030131969720661201 小提示 If you don't know how to determine wheather encounted the end of input: s is a string and n is an integer C++ while(cin>>s>>n) { ... } c while(scanf("%s%d",s,&n)==2) //to see if the scanf read in as many items as you want /*while(scanf(%s%d",s,&n)!=EOF) //this also work */ { ... } 来源 East Central North America 1988 北大OJ平台(代理

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值