计算x的y次幂,并将超大数结果输出到屏幕中(例如3的1000次幂)

对于普通的指数幂计算,我们直接调用C语言库的pow()库函数就可以解决,但是对于将2的10000次方(2^10000),3的1000次方(3^1000)这种计算结果为几百位甚至上千位的数而言,long long数据类型并不能存储下来,所以打印到屏幕中也会出现错误。

解决这种问题的思路,请看下面一段代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>

int main()
{

	int num = 123456790;
	int a = 123, b = 456, c = 789;

	printf("%d\n", num);    //输出结果123456790
	printf("%d %d %d\n", a, b, c); //输出结果123 456 790

	num = 123456790 * 2;  
	a = 123 * 2, b = 456 * 2, c = 790 * 2;
	//这个时候c的结果本来应该为1580,但是我们需要输出的时候保证c只输出三位数,多的一位(1000)进位给b(1000进位后当作b的1)
	//用代码表示的话如下:
	int upnum = 0;//upnum表示进位数
	upnum = c / 1000;  //此时upnum表示c相当于b的进位数
	c = c % 1000;

	upnum = (b + upnum) / 1000; //此时upnum表示b相当于a的进位数
	b = (b + upnum) % 1000;

	c = c + upnum;

	printf("%d\n", num);    //输出结果246913580
	printf("%d %d %d\n", a, b, c); //输出结果246 913 580

	system("pause");
	return EXIT_SUCCESS;
}

另外需要明白一个公式如下:

1234*2=1200*2+34*2  

//这句话和上面的代码综合一下,就是说1234可以分为12和34两段,1234*2的结果为【12这段*2+34这段的溢出】+【34段末两位位数】;

//关键点就是1234这段乘以2,那么1234分为两段12,34。这两段都需要乘以2;


就这样,打算盘一样,进位.

至此,我们已经将需要计算的溢出和乘方计算问题解决了,只用看代码了:
程序用一个含有1024个 无符号整数 (上限65536)的数组来存放各段数据
每一个数是一段,每一个数据可以表示9999这么大的数(便于进位)
计算一次,检查是否超过9999,如果超过,把这一段减去10000,
然后向上一个位(即上一个数)进1(这可以称为 "一万进制 ")
程序可以计算小于2的13605次方,大于0次方的任意的二的乘方,代码如下
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>


int main(void)
{
	static unsigned int temp[1024];/*分段储存数据*/
	unsigned int position = 1;/*记录共有几段*/
	int overflow = 0; /*记录在算每一段时是否溢出*/

	int x, y;//x为底数,y为指数

	printf("请分别输入底数和指数,中间用空格分开\n");
	scanf("%d %d", &x, &y);

	long times = y;  //指数
	long tm_cnt = 0; //乘方次数计数
	long sgn_cnt = 0; //段的位置
	temp[0] = x;/*初始值为x,底数*/

	unsigned int upnum = 0;//每段计算结果的的进位数(如果大于10000进位1,大于20000进位2)
	
	int flag = 0; //标志位
	if (times> 13000)
	{
		printf("your input is too large ");/*检查输入是否越界*/
		exit(0);
	}
	/*开始计算,外层为乘方次数,内层为每一位计算*/
	for (tm_cnt = 0; tm_cnt <times - 1; tm_cnt++)
	{
		for (sgn_cnt = 0; sgn_cnt <position; sgn_cnt++)
		{
			temp[sgn_cnt] *= x;/*相当于乘x*/
			if (overflow == 1) /*检查上次是否有溢出*/
			{
				/*有的话,将溢出加到这一段,同时置溢出为0*/
				temp[sgn_cnt] += upnum;
				upnum = 0; //置零
				overflow = 0;
			}
			if (temp[sgn_cnt]> 9999)
			{
				/*检查本次是否溢出,溢出的话,进位数upnum*/
				//如果底数很大的话,超出了int的取值范围,这里需要加上另外一个条件限制
				upnum = temp[sgn_cnt] / 10000;  //进位数
				temp[sgn_cnt] = temp[sgn_cnt] % 10000;  
				overflow = 1;
			}
		}
		if (overflow == 1)  //下次成方的时候查看段数是否足够,如果不够需要增加
		{
			++position;
			temp[sgn_cnt]+= upnum;
			overflow = 0;

			if (tm_cnt == (times - 2))
			{
				flag = 1;  //如果最后一次乘方发生溢出的话,进行说明
			}

		}
		if (position> 1023)
		{
			printf("times: %d error! ", tm_cnt);
			exit(1);
		}
	}

	//输出第最后一段数字
	if (flag == 1)  //最后一次有溢出
	{
		printf("%d ", temp[sgn_cnt]);
	}
	else  //最后一次没有溢出
	{
		printf("%d ", temp[sgn_cnt - 1]);
	}

	//倒数第二段开始,逆序全部输出
	for (sgn_cnt = position - 2; sgn_cnt >= 0; sgn_cnt--) 
	{
		if (temp[sgn_cnt] <1000)
			printf("0 ");
		if (temp[sgn_cnt] <100)
			printf("0 ");
		if (temp[sgn_cnt] <10)
			printf("0 ");
		printf("%d ", temp[sgn_cnt]);
		if ((sgn_cnt + 1) % 15 == 0)
			printf("\n ");
	}

	system("pause");
	return EXIT_SUCCESS;
}




好了,不知道你看懂了没有。

如果还有写模糊可以参看文档  https://zhidao.baidu.com/question/166472785.html

本人也是从上面学来的 ,哈哈哈


另外推荐一个地址:

http://blog.csdn.net/yhj110911119/article/details/52409143



  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值